我正在尝试使Fortran 77代码库现代化,该代码库大量使用了common
文件中的include
块。我的目标之一是翻译代码库,以便它使用modules
/ common
/ include
构造。但是,代码在各处也使用equivalence
语句,引用了common
变量。不允许equivalence
到module
变量之间来回,所以这是一个问题。
现在,幸运的是,equivalence
语句仅用于别名数组(的一部分),而不再用于不同变量类型之间的“魔术”。因此,我试图通过简单地计算索引偏移量并引用原始数组而不是对它们进行equivalenc
来翻译代码。但是,这导致了一些意外的编译错误和运行时崩溃。
例如,考虑对
的更改IF(RLX*ABS(DXT/(X2-X1)) .GT. 0.05) RLX = 0.05*ABS((X2-X1)/DXT)
到
IF(RLX*ABS(DXT/(COM2(1)-COM1(1))) .GT. 0.05) RLX = 0.05*ABS((COM2(1)-COM1(1))/DXT)
,应该将include
文件的代码更改为
REAL COM1(NCOM), COM2(NCOM)
COMMON/V_VAR1/ X1
COMMON/V_VAR2/ X2
EQUIVALENCE (X1, COM1(1)), (X2, COM2(1))
简单
COMMON COM1(NCOM), COM2(NCOM)
,但导致以下编译错误:
IF(RLX*ABS(DXT/(COM2(1)-COM1(1))) .GT. 0.05) RLX = 0.05*ABS((COM2(1)-COM1(1))/DXT)
1
Error: Missing ')' in statement at or before (1)
不过,这句话对我来说似乎是正确的。那我在这里想念什么?
如果通过将代码更改为来缓解上述问题
DX = COM2(1) - COM1(1)
IF(RLX*ABS(DXT/DX) .GT. 0.05) RLX = 0.05*ABS(DX/DXT)
我没有得到编译错误。但是,我在运行时遇到了Signal: SIGFPE (Arithmetic exception)
,因为出于某种原因,从X1
到COM1(1)
以及从X2
到COM2(1)
的变化似乎无关变量无法获得正确的初始值(导致被零除,并因此导致nan的加法运算,从而导致算术异常)。
很显然,我在这里缺少一些关键的内容,因此我试图找到进行此类翻译的良好参考。有人知道吗?还是有人遇到过这个问题并找到了解决方案?任何帮助将不胜感激。
答案 0 :(得分:0)
如注释中所指出的那样,重构代码后会出现错误,可能是因为您在fixed-form中工作,并且源代码行不能超过72个字符(其余所有字符都将被忽略)。
如果要更新代码,则应保留固定格式并以自由格式编写。有时,编译器假定基于文件扩展名的源代码形式。在这种情况下,可以将文件扩展名从.f
更改为.f90
。否则,您可以将所需格式作为编译器标志传递(在gfortran中为-ffree-form
,在Intel Fortran中为-free
)。
无论如何,如果您陷入固定格式,最好在连续行的第6列中放置一个任意的非空白字符,以进行换行。