Fortran COMMON块初始化

Wol*_*lfy 1 fortran initialization fortran-common-block

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
Run Code Online (Sandbox Code Playgroud)

这是一个可接受的编程实践还是只是一个黑客?此外,由于我正在尝试将代码移植到GFortran,它是否可移植?(我知道声明就像REAL*8只是提示编译器而不保证)

Hig*_*ark 7

EQUIVALENCE什么都不,它肯定不会初始化任何东西,EQUIVALENCE一个定义或声明.这些天(自从Fortran 90标准出版以来一直在不断增长的力量)EQUIVALENCE是一个黑客攻击,应该尽可能避免.

该声明声明2个变量共享存储(Fortran标准称之为存储关联).对此的一种解释是,等价的名称只是别名,但是(ab-)使用该语句允许程序员做一些其他事情,这些事情被21世纪的专业软件工程师认为是狡猾的.

例如,这适用于您发布的代码段,EQUIVALENCE可用于让不同类型的变量共享同一存储.你有一个名为ASCN(隐式)类型REAL*8的数组,这个数组等同于一个被称为类型的数组KLCKF2D(再次隐含)INTEGER.这意味着如果你在一个名称下引用存储,则位模式被解释为REALs,使用另一个名称它们是INTEGERs - 并注意到具有该值的实数的位模式100.0不会(当然)被解释为整数100.

而hackery并不止于此.COMMON块声明的一个作用是将变量放在内存中,在您的情况下,10500 (= 100*21*5)元素ASCN后跟8700元素FEMPTY2.通过一些乘法和加法,您会发现38400 = 2*(10500+8700)在此程序中符合默认整数大小的是4字节,即REAL*8其他变量中使用的s的一半.所以数组KLCKF2D大于ASCN但原始程序员知道下一个17400字节将被占用FEMPTY2.

所以,是的,这可能是一种设置程序内存数据中所有位的方法0,但它(现在被认为是)可怕的黑客攻击.但它应该是可移植的 - 连续的Fortran标准对于从语言和编译器编写器中删除过时的功能一直非常保守,后向兼容性对于Fortran程序员来说非常重要.

哦,并回答你的问题,是COMMON块(注意过去时)FORTRAN77声明和使用全局变量的方式.这些天,语言提供了更安全的选择,即通过将变量包装在一起MODULE并对它们进行USE关联来声明要全局共享的变量.

看到像这样的一条线,我不会感到惊讶

COMMON/COMMF2D/KLCKF2D(38400)
Run Code Online (Sandbox Code Playgroud)

在您的代码中,COMMON块也可以(ab-)用于重命名和重新键入存储位置.

虽然我正在给你的旧代码一个踢,但是这些日子里的隐式输入也不赞成,明显地输入所有声明要好得多.