【发布时间】:2015-11-30 03:32:10
【问题描述】:
在下面的程序中,set_int_array 和 set_real_array 两个例程为虚拟数组定义了一些值,但假设 a(:) 和 r(:) 的初始化(第 1 和 2 行)无意中丢失(即,这两行都应该在正确的程序中取消注释)。我的问题是如何使用一些编译器选项自动检测这些错误。
module mymod
implicit none
contains
subroutine set_int_array ( a )
integer, intent(out) :: a(:)
integer k
! a(:) = 10 !! (1)
do k = 1, size(a)
a(k) = a(k) + k
enddo
end subroutine
subroutine set_real_array ( r )
real, intent(out) :: r(:)
integer k
! r(:) = 10.0 !! (2)
do k = 1, size(r)
r(k) = r(k) + k
enddo
end subroutine
end module
program main
use mymod
implicit none
integer :: a(5)
real :: r(5)
call set_int_array ( a ) ; print *, a(:)
call set_real_array ( r ) ; print *, r(:)
end program
为此,我首先尝试了 gfortran4.8(在 Linux x86_64 上)的以下选项:
gfortran -Wall -fcheck=all test.f90
但这未能检测到丢失的初始化并给出了不正确的结果
1 2 268435459 32730 207
1.0000000 2.0000000 3.0000000 4.0000000 5.0000000
所以我尝试了以下选项来用NaN 初始化r(:):
gfortran -finit-real=snan -ffpe-trap=invalid test.f90
成功捕获了set_real_array 的错误,但没有捕获set_int_array 的错误
-1098847551 59 -1034862589 32608 7941
Program received signal 8 (SIGFPE): Floating-point exception.
Backtrace for this error:
#0 0x00000039becac5f4 in wait () from /lib64/libc.so.6
#1 0x00000039c501400d in ?? () from /usr/lib64/libgfortran.so.3
#2 0x00000039c501582e in ?? () from /usr/lib64/libgfortran.so.3
#3 0x00000039c50146ca in ?? () from /usr/lib64/libgfortran.so.3
#4 <signal handler called>
#5 0x0000000000400bd3 in __mymod_MOD_set_real_array ()
#6 0x0000000000400e69 in MAIN__ ()
#7 0x0000000000400f52 in main ()
因此,我也尝试了带有以下选项的 ifort14.0
ifort -check all test.f90
ifort -check uninit test.f90
但两者都未能检测到错误。事实上,check uninit 选项的手册页说
仅检查不带 SAVE 属性的内在类型 INTEGER、REAL、COMPLEX 和 LOGICAL 的局部 标量变量。
那么可能很自然地没有检测到错误。所以我的问题是:有什么方法可以自动捕获a(:) 和r(:) 的错误?
[ 编辑 ] 我提出这个问题的动机来自 SO 上的a recent post,OP 很难找到错误。原来问题出在evaluate 模块中curve_derivs_alg1() 中使用了未初始化的数组,但我也很难找到错误的精确位置(尽管它可能看起来微不足道)成立!)。 -finit-real-snan -ffpe-trap=invalid 选项在这种情况下有效,但如果整数数组是问题,它应该会变得更加困难......所以我想知道是否有一些方便的选项或方法来跟踪使用未初始化数组的第一个位置。
【问题讨论】:
-
我这里没有资源来写答案,但我怀疑
a(:)不是(在可执行语句中)数组而是数组部分是相关的。 有区别。差异的一个影响是,可以在赋值的 lhs 上对数组执行自动分配,但对 lhs 上的数组部分无效。 -
@HighPerformanceMark 您好,非常感谢您的评论。如果我在问题中的解释具有误导性,我很抱歉,但我没有尝试在两个例程中使用可分配的虚拟数组。它们只是从主程序(其中它们被声明为局部数组)传递过来的。在这里,我正在寻找一种方便的方法来找到使用未初始化数组的第一个位置(请参阅上面的编辑)。
标签: compiler-errors initialization fortran runtime-error