1

我有一个非常旧的程序,我想在我的 64 位计算机上运行。有很多贬值的说法。在调试过程中,我发现很多变量变成了 NaN 或 Infinity... 因此,我将变量从 4 字节更改为 8 字节长(即 REAL 到 REAL*8),但现在两台计算机上的计算和结果有很大不同。有人可以解释一下我是否使用更长的类型真的很重要,为什么在 32 位计算机上一切正常,但在 64 位计算机上我得到 Infinity 和 NaN 值?

PS我使用带有选项的gfortran编译器-fbackslash -ffixed-line-length-0 -std=legacy -g -O0 -fno-inline

问候, kozooh

4

1 回答 1

2

您的问题可能是由于编译器之间的差异而不是机器的位级别之间的差异。例如,某些 FORTRAN 77 编译器隐式应用于save所有过程(子例程和函数)局部变量。这不是标准要求的,不应依赖此行为。当使用现代编译器编译遗留程序时,它经常会导致问题,save如果局部变量应该在过程的调用中保留其值,则需要使用该编译器。不知道g77有没有这个“功能”。您可以使用编译器选项在 gfortran 中打开此行为-fno-automatic

编辑:考虑:

  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. 所以看起来 g77 正在保存局部变量,即使没有使用save. 至少在默认优化级别。

使用带有选项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...

于 2013-07-26T18:22:10.630 回答