首页 > 解决方案 > 用 real*4 读取值为 0 的 real*8 变量会在 fortran 中产生大量数字而不会发出警告

问题描述

用 real*8 读取值为 0 的 real*4 变量会产生大量结果,有时不会发出警告。

我不擅长 Fortran。我只是在运行从别人那里得到的 Fortran 代码,结果出现了分段错误。当我调试它时,我发现其中一个子例程正在读取一个用 real*8 定义的值为 0 的变量,因为 real*4 结果是一个很大的值。

我试图用简单的代码重现它,但编译器显示参数不匹配的警告。我不得不嵌套代码以在简单的代码中重现抑制的警告,但我不确定抑制警告的确切条件是什么。

实际上,出于某种原因,我怀疑这可能是我的编译器的问题,因为代码(不是示例代码,原始代码)在给我代码的人的 PC 上运行良好。

文件hello.f

  implicit none
  call sdo()
  END

文件test.f

  subroutine sdo()
  implicit none
  real*4 dsecs
  dsecs=0
  write(0,*) dsecs
  call sd(dsecs)
  return
  end

文件test2.f

  subroutine sd(dsecs)
  implicit none
  real*8 dsecs
  write(0,*) dsecs
  return
  end

编译和执行:

$ gfortran -o hello hello.f test.f test2.f
$ ./hello

预期结果:

0. 00000000
0. 0000000000000000

实际结果:

0. 00000000
-5.2153889789423361E+223

标签: fortran

解决方案


这不是编译器的问题。这是代码的问题。您的代码确实向我发出了警告,表明您正在做一些邪恶的事情,这是应该的。认为dsecs是4字节长的子程序发送了4字节。认为dsecs是8字节长的子程序看了8字节。其他 4 个字节是什么?谁知道。两者混在一起时会是什么样子?可能不是你想要的。这就像意外地得到一勺半冰淇淋和半垃圾:不太可能按照您的想法品尝。

这是用那个经典笑话非常简单地解决的问题之一:“医生,医生,我这样做的时候很痛 ” - “那么……不要那样做。”

编辑:对不起,我作弊了。我没有将它们编译为单独的程序。当我这样做时,我不会收到警告。这也是正常的 - 在编译步骤,您没有指定外部子例程的外观,因此它不会抱怨,并且在链接步骤编译器不再检查。


推荐阅读