fortran - 用 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
解决方案
这不是编译器的问题。这是代码的问题。您的代码确实向我发出了警告,表明您正在做一些邪恶的事情,这是应该的。认为dsecs
是4字节长的子程序发送了4字节。认为dsecs
是8字节长的子程序看了8字节。其他 4 个字节是什么?谁知道。两者混在一起时会是什么样子?可能不是你想要的。这就像意外地得到一勺半冰淇淋和半垃圾:不太可能按照您的想法品尝。
这是用那个经典笑话非常简单地解决的问题之一:“医生,医生,我这样做的时候很痛! ” - “那么……不要那样做。”
编辑:对不起,我作弊了。我没有将它们编译为单独的程序。当我这样做时,我不会收到警告。这也是正常的 - 在编译步骤,您没有指定外部子例程的外观,因此它不会抱怨,并且在链接步骤编译器不再检查。
推荐阅读
- c# - BadRequest .Net Core API 的状态码问题
- python - 关于使用python和opencv3进行筛选映射的问题
- android - 在不绘制它们的情况下访问android的相机框架并将它们发送回c++
- sql - 查询查找第二个字段不同的重复记录
- python - gensim lemmatize 错误生成器引发 StopIteration
- java - 具有需要枚举参数的注释的 clojure gen-class
- python - 使用 pyinstaller 将 .py 转换为 .exe 后缺少模块
- c++ - QTcpSocket:通信数小时后服务器响应延迟
- r - 为什么在 R 中使用管道运算符会出现以下错误?
- express - cookie 中的 Express Gateway JWT 验证