我在一些旧版 fortran 中添加了一个数据收集例程。为了便于使用,我用 C 编写了文件 i/o 例程。
我正在使用 gcc 和 gfortran。
问题:在看似无害的 C 函数调用过程中,一些 fortran 变量名称被覆盖。
C 函数都是 void 类型,名称都是小写,所有参数都是指针,函数名称都包含一个尾随“_”,并且作为子例程从 Fortran 调用。我以前做过。gfortran 强制所有 Fortran 符号为小写,并且所有入口点都附加一个“_”以区别于同名 C 入口点。
这是 C 文件的片段:
#define MAXFILES 20
FILE *outfile[MAXFILES];
/* int2char_ generates a left zero padded string (*theChar) from an int
(*theInt), that is *numChar characters long. E.g, called from fortran:
string *5 arun
integer nrun
integer nnchar
nrun = 231
nchar = 4
call int2char (nrun, arun, nnchar)
c... returns '0231' in arun
*/
void int2char_ (int *theInt, char *theChar, int *numChar) {
int nchar;
nchar = *numChar;
if (nchar > 9) nchar = 9;
if (nchar < 1) nchar = 1;
sprintf(theChar, "%*.*d", nchar, nchar, *theInt);
return;
} // end of int2char
void openwrite_ (char *filename, int *unit) {
outfile[*unit] = fopen (filename, "w");
return;
} /* end of openWrite */
void closefile_ (int *unit) {
int closed;
if (outfile[*unit]) {
closed = fclose (outfile[*unit]);
}
return;
}
void writefirststr_ (char *string, int *unit) {
int printed;
printed = fprintf (outfile[*unit], "%s", string);
// printed = fputs (string, outfile[*unit]);
return;
}
这是被踩到的 Fortran 变量的声明:
c...................
c"Display the mass matrix when DISMAT is set TRUE "
LOGICAL, save :: DISMAT
c...................
注意:我最初使用volatile
声明限定符代替save
限定符。没有不同。
这是电话:
c...................
c... build file name
numchar = 4
call int2char (nrun, filenumber, numchar)
begin = 1
end = len_trim(fileprefix)
filename(begin:end) = fileprefix
begin = end + 1
end = begin + 3
filename(begin:end) = filenumber
begin = end + 1
end = begin + 3
filename(begin:end) = fileext
begin = end + 1
filename(begin:begin) = char(0)
c... close open file
call closefile (lunit)
c... open file
call openWrite (filename, lunit)
c... write header(s)
call writeFirstStr (atime', lunit)
c...................
当我执行该call writefirstStr ('time', lunit)
行时会出现问题。
atime
是一个character*5
被数据化为 'time' 并显式地以 null 终止的:time(5:) = char(0)
。单步writefirststr_()
执行显示没有问题,并且正确的信息被写入文件。
如果我(通过 gdb)在 之后跳转到 return 语句(在包含上述代码片段的 fortran 例程中)call openWrite (filename, lunit)
,则没有问题。
调用writeFirstSt
r 是覆盖 fortran 变量的原因DISMAT
。我还应该注意,这DISMAT
不在上面进行 C 语言调用的例程中。
我还没有尝试save
在所有 Fortran 变量上使用限定符——由于遗留代码的数量导致的后勤问题。
有人有什么想法吗?