InsideLoop
InsideLoop

Reputation: 6255

Checking the size of an array passed to a function

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

Upvotes: 6

Views: 1747

Answers (2)

francescalus
francescalus

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

PTRK
PTRK

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

Related Questions