2

I am trying to compile a code using gfortran. The subroutine plumed_f_gcmd is where I am having some trouble. Here is the piece of the code

        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))

the compiler throws the following error:

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)

First of all I don't quite understand how in a subroutine, the second input can be once a number and once a string? does '//char(0)' somehow changes the string to another data type? Can someone please explain this to me?

And my second question is why the error is not happening also for the case of the third line (PLUMED.OUT)?

I don't know how but some C and C++ wrappers are also involved; this is the subroutine in C:

void plumed_f_gcmd(char*key,void*val){
   plumed_gcmd(key,val);
}
11
  • 3
    To me that looks like you're exceeding the permitted line lengths. Is this meant to be fixed-form source (what's the file extension/command line)? Commented Apr 15, 2016 at 12:51
  • In fixed form as here, characters after column 72 are ignored. Commented Apr 15, 2016 at 13:10
  • Yes, changes made by LRiO are destructive, I am rolling them back. Commented Apr 15, 2016 at 13:24
  • @francescalus: FORTRAN requires eight spaces at the start of each line? TIL. That's fine. I really don't see why it matters here as the context is utterly clear and all that space does is waste pixels, but that's fine. Commented Apr 15, 2016 at 14:03
  • @SergeyA: Unfortunately, you also rolled back the syntax highlighting fix, so now the code is being rendered as if it were C++, which is obviously wrong and very confusing when you look at the code with your eyes. Why did you choose to do that? Commented Apr 15, 2016 at 14:03

1 Answer 1

2

As suggested in the comments, the error message

Error: Syntax error in argument list at (1)

appears most likely because your Fortran code is written in fixed-format and only the first 72 characters are processed by the compiler. To avoid this, please try an option like

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

which allowa lines of any length. The reason why no error occurs for the third line (with "PLUMED.OUT") is probably that the line is within 72 characters (but very close!)


As for char(0) (the null character), this is attached to Fortran strings so that they can be processed by C routines as a null-terminated string. Please note that // in Fortran represents a string concatenation (similar to "hello" + "world" in other languages), not some special thing that changes the string to another data type.


As for why the second argument of plumed_f_gcmd() can be once a number and once a string, I guess this routine probably reads the first argument (or "command") and makes an appropriate type casting in some routine (please see the original code for details). The following is such an example, where integer, real, and string variables are passed to the same routine 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 ); 
}

Compile

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

Result

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

(Please note that the above C routine may not be portable for compilers other than gcc/gfortran. To make it portable, please use the interoperability features of modern Fortran, e.g., this page).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.