Fortran 如何从等价转换为索引偏移

Fortran 如何从等价转换为索引偏移,fortran,equivalence,Fortran,Equivalence,我正在尝试使Fortran 77代码库现代化,该代码库大量使用include文件中的common块。我的目标之一是翻译代码库,使其使用模块而不是此通用/包含构造。然而,代码也在此处和那里使用等价性语句,引用公共变量。不允许等价于模块变量,因此这是一个问题 现在,幸运的是,equivalence语句只用于别名(部分)数组,而不用于不同变量类型之间的“magic”。因此,我试图通过简单地计算索引偏移量并引用原始数组来翻译代码,而不是将它们等效。但是,这会导致一些意外的编译错误和运行时崩溃 例如,考虑

我正在尝试使Fortran 77代码库现代化,该代码库大量使用
include
文件中的
common
块。我的目标之一是翻译代码库,使其使用
模块
而不是此
通用
/
包含
构造。然而,代码也在此处和那里使用
等价性
语句,引用
公共
变量。不允许
等价于
模块
变量,因此这是一个问题

现在,幸运的是,
equivalence
语句只用于别名(部分)数组,而不用于不同变量类型之间的“magic”。因此,我试图通过简单地计算索引偏移量并引用原始数组来翻译代码,而不是将它们等效。但是,这会导致一些意外的编译错误和运行时崩溃

例如,考虑从

IF(RLX*ABS(DXT/(X2-X1)) .GT. 0.05) RLX = 0.05*ABS((X2-X1)/DXT)

,它应该将
包含的文件代码从

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)
我没有得到编译错误。然而,我在运行时遇到了SIGFPE(算术异常)
,因为出于某种原因,从
X1
COM1(1)
X2
COM2(1)
的变化导致看似不相关的变量无法获得正确的初始值(这导致被零除,从而导致nan的加法,从而导致算术异常)


显然,我在这里遗漏了一些关键的东西,所以我试图找到一个很好的参考来进行这种翻译。有人知道这样的事情吗?或者有人以前遇到过这个问题并找到了解决方案吗?如果有人能帮我解决,我们将不胜感激。

正如评论中所指出的,错误是在重构代码pro之后出现的bably,因为您正在中工作,并且源行不能超过72个字符(所有剩余字符都将被忽略)

如果要使代码现代化,则应保留固定格式,以自由格式编写。有时编译器会根据文件扩展名采用源格式。如果是这种情况,可以将文件扩展名从
.f
更改为
.f90
。或者,可以将所需格式作为编译器标志传递(
-ffree form
在gfortran中,而
-free
在英特尔Fortran中)


如果在任何情况下您陷入固定格式,您最好通过在连续行的第6列添加任意非空字符来进行行延续。

在行中添加额外字符很容易使行长度超出限制,因此请检查新行的长度。此外,“简化”单行与它所替换的三行有很大的不同,它有“<代码> NCOM在公用块中指定的数字存储单元的数量。您是否受限于固定格式?您可以在新代码中使用自由格式吗?如果您正在更新代码,我看不出有什么固定格式写入它的感觉。将所有大写字母和难看的
.GT.
现代化为
>
。但我同意在测试更改之前不应立即更改太多。我也同意您的错误看起来像是一个行长度限制问题(有大量重复项可用)。Fortran 77中89个字符太多(更一般地说,是固定格式源代码)。在固定源格式中,对语句在一行中的显示位置有限制。如果源行仅包含默认类型的字符,则应正好包含72个字符;否则,其最大字符数取决于处理器。
DX = COM2(1) - COM1(1)
IF(RLX*ABS(DXT/DX) .GT. 0.05) RLX = 0.05*ABS(DX/DXT)