我有一个非常旧的程序,我想在我的64位计算机上运行。有很多折旧的陈述。在调试过程中,我发现很多变量都变成了NaN或Infinity ...因此,我将变量从4字节更改为8字节长(即REAL到REAL * 8),但现在两台计算机上的caluclations和结果都有很大不同。如果我使用更长的类型以及为什么在32位计算机上一切正常但是在64位上我得到无限和NaN值,有人可以解释我是否真的有用吗?
P.S。我使用 gfortran 编译器和-fbackslash -ffixed-line-length-0 -std=legacy -g -O0 -fno-inline
选项
此致 kozooh
答案 0 :(得分:2)
您的问题可能是由于编译器之间的差异而不是机器的位级之间的差异。例如,一些FORTRAN 77编译器隐式地将save
应用于所有过程(子例程和函数)局部变量。标准不要求这样做,不应依赖此行为。当使用现代编译器编译遗留程序时,它经常会导致问题,如果局部变量应该在过程的调用中保留其值,则需要使用save
。我不知道g77是否有这个“功能”。您可以使用编译器选项-fno-automatic
在gfortran中启用此行为。
编辑:考虑:
subroutine MySub
logical FirstCall
save FirstCall
data FirstCall / .TRUE. /
integer I
if ( FirstCall ) then
I = 0
FirstCall = .FALSE.
end if
I = I + 1
write (6, *) "Call", I
end
program main
integer j
do j=1, 4
call MySub ()
end do
end program main
使用g77(无编译器选项)编译,输出为:
Call 1
Call 2
Call 3
Call 4
局部变量I
在MySub
的调用中保留其值。因此,即使没有save
请求,g77也会保存本地变量。至少在默认优化级别。
使用选项fbackslash -ffixed-line-length-0 -std=legacy -g -O0 -fno-inline
的gfortran编译,输出相同。现在更改为-O3
,输出为:
Call 1
Call 2
Call 3
Call 129
有时I
会保留其价值,有时则不会。
将程序的一行更改为:save FirstCall, I
,并始终保留该值:
Call 1
Call 2
Call 3
Call 4
试试-fno-automatic
...