我在一个大型程序中发现了一个错误,该程序的子例程编写为:
program main
implicit none
real, dimension(6) :: x
call f(x, 7)
write (*,*) x
contains
subroutine f(x, n)
integer :: n
real, dimension(n) :: x
integer :: i
do i = 1, n
x(i) = 0.0
end do
end subroutine f
end program main
即使代码显然有错误,该程序也可以与ifort和gfortran一起运行,并且可以进行边界检查。是否可以捕获此类错误?
PS:这是两个可以正常运行的二进制文件的命令
ifort -check all main.f90 -o main
gfortran -fbounds-check main.f90 -o main
答案 0 :(得分:2)
免责声明:作者要求提供一个选项来捕获该错误。这个答案没有提供。
如果数组是假定的形状(dimension(:)
),则执行检查:
ifort 15.5
forrtl: severe (408): fort: (2): Subscript #1 of the array X has value 7 which is greater than the upper bound of 6
gfortran 6.1.0
Fortran runtime error: Index '7' of dimension 1 of array 'x' above upper bound of 6
而当它和假定的大小(dimension(*)
)或显式形状(dimension(n)
)却不是。它可能是经过专门设计的。
ifort手册
不对以下数组执行数组边界检查 伪参数,其中最后一个维度边界指定为 *或上下尺寸均为1时。
gfortran手册没有详细说明这一点
答案 1 :(得分:2)
这是一类重要的编程错误,在检测实例时,编译器不会太大。正如问题所指出的那样,使用数组访问范围检查进行编译时,Intel和GNU编译器均无法检测到问题。
确实,我不知道其他标志会在运行时打开编译器中的此类检查。
但是,在某些情况下,gfortran和ifort都可以捕获该错误。当实际变量或自变量具有由常量表达式给出的显式大小并且子例程的接口为“已知”(不一定是显式)时,可能会检测到错误。使用gfortran,位于同一文件中的过程可以启用此检查,并且使用ifort选项-warn interfaces
(可能在-gen_interfaces
之后)也可以执行此操作。
现在,这是一个重要的错误类别,我们可以超越问题的简单范围。如answer by PTRK所述,可以通过不使用显式形状假人来减轻错误。
此外,作为一个示例,NAG编译器确实提供了这样的运行时检查,以使实际参数不短于关联的伪参数。问题的代码与-C
一起编译,给出了运行时错误:
line 8: Invalid reference to procedure MAIN:F - Dummy array X (number 1) has 7 elements but actual argument only has 6 elements
Program terminated by fatal error
始终值得考虑使用各种工具来捕获潜在编程错误或不明智做法的不同方面。