Reputation: 6255
I have found a bug in a large program where a subroutine was written as:
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
This program runs fine with both ifort and gfortran and bounds checking even though the code is obviously buggy. Is there an option to catch those kind of bugs?
PS: Here are the two commands that generate binaries that run fine
ifort -check all main.f90 -o main
gfortran -fbounds-check main.f90 -o main
Upvotes: 6
Views: 1747
Reputation: 32366
This is an important class of programming error where compilers are not too great when it comes to detecting instances. As the question notes, both the Intel and GNU compilers fail to detect a problem when compiling with array access bounds checking.
Indeed, I am not aware of other flags which turn on such checking in the compiler at run-time.
However, in some cases both gfortran and ifort can catch the error. When the actual or argument has an explicit size given by a constant expression and the interface of the subroutine is "known" (not necessarily explicit) the error may be detected. With gfortran, the procedure being in the same file may enable this checking and with ifort the option -warn interfaces
(maybe after -gen_interfaces
) does the same.
Now, this as this is an important class of error we can go beyond the simple limits of the question. As the answer by PTRK says, the error can be mitigated by not using explicit shape dummies.
Additionally, the NAG compiler, as one example, does offer such run-time checks for actual arguments being no shorter than associated dummy arguments. Compiled with -C
the code of the question gives the run-time error:
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
It is always worth considering a variety of tools to catch different aspects of potential programming errors or unwise practices.
Upvotes: 2
Reputation: 929
Disclaimer: The author ask for an option to catch the bug. This answer doesn't provide it.
If the array is an assumed shaped (dimension(:)
), the check is performed:
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
whereas when its and assumed size (dimension(*)
) or explicited shape (dimension(n)
) it is not. It may be purposely designed.
ifort manual
Array bounds checking is not performed for arrays that are dummy arguments in which the last dimension bound is specified as * or when both upper and lower dimensions are 1.
gfortran manual dosn't detail that point
Upvotes: 2