Fortran新手在这里,我被要求使用Salford / Silverfrost编译器(最初的开发人员去世)处理用Fortran 77编写的旧Fortran代码库。
原始开发人员广泛使用名为COMMON
的块(用于模拟全局变量,AFAIU),并在需要时使用EQUIVALENCE
来(重新)初始化块,如下面的代码片段所示:
IMPLICIT REAL*8 (A-H,O-Z)
COMMON/COMMF2D/
* ASCN(0:99,0:20,0:4)
*,FEMPTY2(8700)
DIMENSION KLCKF2D(38400)
EQUIVALENCE (KLCKF2D,ASCN)
DO I= 1,38400
KLCKF2D(I)= 0
END DO
这是一种可接受的编程习惯还是只是一种黑客行为?此外,由于我正在尝试将代码移植到GFortran,它是否可移植? (我知道像REAL*8
这样的声明只是编译器的提示而不是保证)
答案 0 :(得分:7)
EQUIVALENCE
不会做任何事情,它肯定不会初始化任何内容,EQUIVALENCE
是一个定义或声明。这些天(自从Fortran 90标准出版以来,力量一直在增长)EQUIVALENCE
是一个黑客攻击,应该尽可能避免。
该声明声明2个变量共享存储(Fortran标准称之为存储关联)。对此的一种解释是,等价的名称只是别名,但是(ab-)使用该语句允许程序员做一些其他事情,这些事情被21世纪的专业软件工程师认为是狡猾的。
例如,这适用于您发布的代码段,EQUIVALENCE
可用于让不同类型的变量共享相同的存储空间。你有一个名为ASCN
的数组,它是(隐含地)类型为REAL*8
的数组,等同于一个名为KLCKF2D
的数组,它是(再次隐含地)类型为INTEGER
的数组。这意味着,如果您在一个名称下引用存储,则位模式将被解释为REAL
s,使用另一个名称INTEGER
s - 并注意位的模式值100.0
的实数不会(当然)被解释为整数100
。
而hackery并不止于此。 COMMON
块声明的一个效果是将变量放在内存中,在您的情况下,10500 (= 100*21*5)
的{{1}}元素后跟ASCN
元素8700
}}。通过一点乘法和加法,您会发现FEMPTY2
符合此程序中的默认整数大小为4字节,即其他变量中使用的38400 = 2*(10500+8700)
的大小的一半。因此,数组REAL*8
大于KLCKF2D
,但原始程序员知道ASCN
将占用下一个17400
个字节。
所以是的,这可能是一种将程序内存数据中的所有位设置为FEMPTY2
的方法,但它(现在被认为是)是一个可怕的黑客。但它应该是可移植的 - 连续的Fortran标准对于从语言和编译器编写器中删除过时的功能一直非常保守,后向兼容性对于Fortran程序员来说非常重要。
哦,回答你的问题,是0
块(注意过去时)FORTRAN77声明和使用全局变量的方式。现在,这种语言提供了更安全的选择,可以通过将变量包装在COMMON
和MODULE
中来声明要全局共享的变量 - 将它们关联起来。
看到像
这样的行,我不会感到惊讶USE
在您的代码中,COMMON/COMMF2D/KLCKF2D(38400)
块也可以(ab-)用于重命名和重新键入存储位置。
虽然我正在给你的旧代码提供帮助,但是这些日子里的隐式输入也不赞成,更好地明确键入所有声明。