2016-04-15 4 views
1

Ich versuche, einen Code mit gfortran zu kompilieren. Das Unterprogramm plumed_f_gcmd ist, wo ich einige Probleme habe. Hier ist das Stück des CodesSyntaxfehler in der Argumentliste einer Subroutine

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

die Compiler die folgenden Fehler:

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) 

Zunächst einmal kann ich nicht ganz verstehen, wie in einem Unterprogramm kann der zweite Eingang einmal eine Zahl sein, und einmal eine Schnur? ändert '//char(0)' irgendwie die Zeichenfolge in einen anderen Datentyp? Kann mir bitte jemand das erklären?

Und meine zweite Frage ist, warum der Fehler nicht auch für den Fall der dritten Zeile (PLUMED.OUT) auftritt?

Ich weiß nicht, wie aber einige C und C++ Wrapper beteiligt sind; dies ist das Unterprogramm in C:

void plumed_f_gcmd(char*key,void*val){ 
    plumed_gcmd(key,val); 
} 
+3

Für mich sieht das so aus, als ob Sie die zulässigen Leitungslängen überschreiten. Ist dies eine feste Quelle (was ist die Dateierweiterung/Befehlszeile)? – francescalus

+0

In fester Form wie hier werden Zeichen nach Spalte 72 ignoriert. – Gilles

+0

Ja, Änderungen von LRiO sind destruktiv, ich rolle sie zurück. – SergeyA

Antwort

1

Wie in den Kommentaren vorgeschlagen, die Fehlermeldung

Error: Syntax error in argument list at (1)

erscheint sehr wahrscheinlich, weil Ihr Fortran-Code in festem Format geschrieben und nur die ersten 72 Zeichen sind vom Compiler verarbeitet. Um dies zu vermeiden, versuchen Sie bitte eine Option wie

, die Zeilen beliebiger Länge zulassen. Der Grund, warum kein Fehler für die dritte Zeile auftritt (mit „PLUMED.OUT“) ist wahrscheinlich, dass die Linie innerhalb von 72 Zeichen (aber ganz in der Nähe!)


Was char(0) (das Null-Zeichen), das ist an Fortran-Zeichenfolgen angehängt, so dass sie von C-Routinen als null-terminated string verarbeitet werden können. Bitte beachten Sie, dass // in Fortran eine String-Verkettung darstellt (ähnlich wie "hello" + "world" in anderen Sprachen), nicht eine spezielle Sache, die die Zeichenfolge in einen anderen Datentyp ändert.


Was, warum das zweite Argument von plumed_f_gcmd() einmal eine Zahl und einmal eine Zeichenfolge sein, ich denke, diese Routine wahrscheinlich liest das erste Argument (oder „command“) und macht einen geeigneten Typ Gießen in einem gewissen Routine (Bitte beachten Sie das Original code für Details). Das Folgende ist ein solches Beispiel, wo integer, real, und Stringvariablen übergeben werden, auf die gleiche 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); 
} 

Compilieren

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

Ergebnis

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 

(Bitte beachten Sie, dass die obige C-Routine möglicherweise nicht für andere Compiler als gcc/gfortran tragbar ist. Um es portabel zu machen, benutzen Sie bitte die Interoperabilitätseigenschaften von modernem Fortran, z. B. dieses page).

Verwandte Themen