子例程的参数列表中的语法错误

时间:2016-04-15 12:39:07

标签: compiler-errors fortran

我正在尝试使用gfortran编译代码。子程序plumed_f_gcmd是我遇到麻烦的地方。这是代码片段

        call plumed_f_gcmd("setMDTimeUnits"//char(0),timeUnits)
        call plumed_f_gcmd("setPlumedDat"//char(0),"plumed.dat"//char(0))
        call plumed_f_gcmd("setLogFile"//char(0),"PLUMED.OUT"//char(0))
        call plumed_f_gcmd("setNatoms"//char(0),natms)
        call plumed_f_gcmd("setMDEngine"//char(0),"dlpoly1.90"//char(0))

编译器抛出以下错误:

call plumed_f_gcmd("setPlumedDat"//char(0),"plumed.dat"//char(0
                                                               1
Error: Syntax error in argument list at (1)

call plumed_f_gcmd("setMDEngine"//char(0),"dlpoly1.90"//char(0)
                                                               1
Error: Syntax error in argument list at (1)

首先,我不太明白如何在子程序中,第二个输入可以是一个数字,一次是一个字符串? '//char(0)'以某种方式将字符串更改为另一种数据类型?有人可以向我解释一下吗?

我的第二个问题是为什么第三行(PLUMED.OUT)的情况也没有发生错误?

我不知道如何,但也涉及一些C和C ++包装器;这是C:

中的子程序
void plumed_f_gcmd(char*key,void*val){
   plumed_gcmd(key,val);
}

1 个答案:

答案 0 :(得分:1)

根据评论中的建议,错误消息

  

错误:参数列表中的语法错误(1)

最有可能出现,因为您的Fortran代码是以固定格式编写的,编译器只处理前72个字符。为避免这种情况,请尝试选择

gfortran -ffixed-line-length-none yourcode.f

允许任何长度的线条。第三行(“PLUMED.OUT”)没有发生错误的原因可能是该行在72个字符内(但非常接近!)

对于char(0)(空字符),它附加到Fortran字符串,以便C例程可以将它们作为null-terminated string处理。请注意,Fortran中的//表示字符串连接(类似于其他语言中的"hello" + "world"),而不是将字符串更改为其他数据类型的一些特殊内容。

至于为什么plumed_f_gcmd()的第二个参数可以是一个数字,一次是一个字符串,我想这个例程可能会读取第一个参数(或“命令”)并在某个例程中进行适当的类型转换(有关详细信息,请参阅原始code。以下是这样一个示例,其中将整数,实数和字符串变量传递给同一例程sub()

fort.f90:

program main
    implicit none
    integer       :: intval
    real          :: realval
    character(50) :: str

    intval = 777 ; realval = 3.14 ; str = "world"

    call sub( "ShowInteger" // char(0), 100    )
    call sub( "ShowInteger" // char(0), intval )

    call sub( "ShowReal"    // char(0), 1.0     )
    call sub( "ShowReal"    // char(0), realval )

    call sub( "ShowString"  // char(0), "hello"   // char(0) )
    call sub( "ShowString"  // char(0), trim(str) // char(0) )
end

sub.c:

#include <stdio.h>
#include <string.h>

void sub_ ( char* cmd, void* ptr )
{
    printf( "command = %s\n", cmd );

    if ( strcmp( cmd, "ShowInteger" ) == 0 ) printf( "int   : %20d\n",   *((int*)ptr) );
    if ( strcmp( cmd, "ShowReal"    ) == 0 ) printf( "float : %20.5f\n", *((float*)ptr) );
    if ( strcmp( cmd, "ShowString"  ) == 0 ) printf( "str   : %20s\n",    (char*)ptr ); 
}

编译

gfortran -c fort.f90
gcc -c sub.c
gfortran fort.o sub.o

结果

command = ShowInteger
int   :                  100
command = ShowInteger
int   :                  777
command = ShowReal
float :              1.00000
command = ShowReal
float :              3.14000
command = ShowString
str   :                hello
command = ShowString
str   :                world

(请注意,上述C例程可能不适用于gcc / gfortran以外的编译器。为了使其可移植,请使用现代Fortran的互操作性功能,例如,page)。