2

我正在尝试将代码从 ifort 编译器移植到 ibm xlf 编译器。它在 redhat 上的 ifort 下运行良好,但在 AIX 系统上的 xlf 下给出的结果包含“NaNQ”。事实证明,代码中有一个数组边界读取会导致这个问题,这里有一个简化的例子:

program main                                                                                                                                                    
implicit none                                                                                                                                                   
real(8)::a(1,0:10)=0.D0                                                                                                                                         

print *, a(1,-1)                                                                                                                                                
end program main 

使用这两个编译器我可以成功编译它,没有任何错误或警告。在 ifort 我得到结果:

0.000000000000000E+000

但是在 xlf 上,我得到:

0.247032822920623272E-322

但是,如果我在边界之外阅读更多内容,xlf 将无法编译,但 ifort 编译成功。

program main                                                                                                                                                    
implicit none                                                                                                                                                   
real(8)::a(1,0:10)=0.D0                                                                                                                                         

print *, a(1,-3:-1)                                                                                                                                                
end program main

在 ifort 我得到:

0.000000000000000E+000  0.000000000000000E+000  0.000000000000000E+000

在 xlf 上它不会编译:

"1.f90", line 5.9: 1516-023 (S) Subscript is out of bounds.
** main   === End of Compilation 1 ===
1501-511  Compilation failed for file 1.f90.

为什么 ifort 和 xlf 在这种跨界读取上采取不同的方式?有什么办法让编译器严格检查并防止发生跨界读取?毕竟,我花了很长时间才在我们的代码中发现这个错误,因为我们小组已经使用这个代码超过 15 年,在 ifort 上没有任何问题。谢谢。

4

1 回答 1

4

大多数 Fortran 编译器都有在运行时检查数组边界错误的选项。在这些具有常量索引的示例中,可以在编译时发现错误,一些编译器而不是其他编译器在不使用非默认选项的情况下会这样做。使用 ifort 使用 -check bounds 请求数组边界检查。您可以使用 -check all 进行额外检查。这些选项通常不是默认选项,因为存在运行时成本。但是得到错误答案的成本可能要高得多!我发现运行时成本经常低得惊人,建议在代码开发期间使用运行时检查,如果运行时成本可以接受,甚至在生产中使用。

于 2012-11-09T18:26:54.953 回答