2013-03-14 191 views
2

来自在商业程序的程序员手册中发布的源代码,我已经隔离了一个令我困惑的代码片断。FORTRAN在哪里存储局部变量?

下面的函数预计会被内核多次调用,应该实现一个组件在多个互连组件中组成的时间行为(我已经从函数原型中删除了输入/输出参数,因为他们与我打算提出的观点无关)。

为区分同一块类型的不同实例,内核在INFO(1)元素中传递一个实例号。

据我了解,这个程序的设计者花费了大量的努力,试图节省从每个调用中有意义的名称复制参数值从PAR向量到局部变量的时间(如如果他们不知道编译器可以做的优化)。在我看来,他们只想在第一次调用时将它们分配给局部变量,或者当调用者切换到相同类型的不同实例时。

但是我无法理解,如果局部变量没有用“save”关键字声明为静态,这是如何工作的。 FORTRAN是否静态存储局部变量,即不在堆栈上? (如果这个问题听起来很蠢,我很抱歉,我习惯于C/C++语言)

谢谢。

SUBROUTINE TYPE151(PAR, INFO, *) 

    IMPLICIT NONE 

    INTEGER*4 INFO(15), IUNIT 
    DOUBLE PRECISION PAR, QMAX 

    PARAMETER (NP=1) 
    DIMENSION PAR(NP) 

    ! First call 
    IF (INFO(7).EQ.-1) THEN 

     IUNIT = INFO(1) 

     QMAX = PAR(1) 

     RETURN 1 
    ENDIF 

    ! later calls 
    IF(INFO(1).NE.IUNIT) THEN 

     IUNIT = INFO(1) 

     QMAX = PAR(1) 
    ENDIF 

    ! Making use of QMAX in some ways... 

    RETURN 1 
END SUBROUTINE TYPE151 
+0

我几十年来一直没有与FORTRAN合作过,但从历史上看,你是正确的; FORTRAN不支持递归并静态存储所有局部变量。我确信有现代版本的FORTRAN,这不再是真实的,但可能不是全部。 – 2013-03-14 16:10:48

+0

子程序中的局部变量在返回后变得未定义,除非它具有保存属性,或者它在模块级别声明并且模块由主程序使用。在接下来的Q中接受的解决方案是好的。 http://stackoverflow.com/questions/2893097/fortran-save-statement。所以我不明白你的代码是如何工作的...... – yosukesabai 2013-03-14 16:43:12

+0

我也没有,也考虑到这个模式,发表在手册,已经传播到许多用户书面块...我不相信每个人都在编译与旧的编译器。感谢您的意见,但请考虑上述事情不是“我的”代码! – Anton 2013-03-15 09:08:07

回答

2

存储方法不是语言标准的一部分。旧的FORTRAN编译器(FORTRAN 77及更早版本)经常静态存储所有变量。该语言要求您对变量使用“SAVE”,以便在调用过程时保留这些值。但是许多程序员忽略了这一要求,并且依赖于所有变量保留其价值的行为,因为FORTRAN 77时代的典型编译器设计。

现代Fortran编译器通常以不同的方式使用内存,如果忽略SAVE,程序的局部变量并不总是保留其值。当使用当前编译器编译旧程序时,这经常会导致错误。编译器通常提供恢复旧行为的选项。否则,在一个大的遗留程序中识别需要将SAVE属性添加到其声明中的所有变量可能是一项很大的工作。

+0

非常感谢。 – Anton 2013-03-15 09:09:25

相关问题