Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Bounds checking, zero sized array and sequence association

Jobie_G_
Beginner
1,255 Views

I work on code that frequently relies on sequence association when passing arrays as arguments. Zero sized arrays are not a problem during program execution but when I turn on bounds checking there doesn't seem to be any way to have a valid index for the actual array argument.

This example shows a simple version where array(0) and array(1) are both out of bounds access. Of course, I could just pass the whole array instead of relying on sequence association, but in many cases the sequence association is a way to pass array sections and it's not possible to find a method that works with bounds checking for both zero sized arrays and non-zero sized arrays. Is there any way to enable bounds checking that "works" in this situation? ("works" = does what I want it to, not what I tell it to)

program zero

  integer,parameter :: array_dim=0
  integer :: array(array_dim)

  array=1
  
  call print_array(array(0),array_dim)

END PROGRAM zero

subroutine print_array(array,size)
  integer :: array(*),size
  integer :: i
  
  do i=1,size
    write(*,*)i,array(i)
  end do
  
end subroutine print_array

 

0 Kudos
2 Replies
Steven_L_Intel1
Employee
1,255 Views

Not that I can think of offhand. As you note, array(0) is indeed out-of-bounds. With sequence association you have to pass an array element, and there aren't any.

I would suggest a modification of the subroutine, though:

subroutine print_array(array,size)
  integer :: size,array(size)     

This is an "adjustable array" and allows checking of the bounds, which (*) does not. Note that the declaration of "size" must precede that of array in order to be standard-conforming.

0 Kudos
Jobie_G_
Beginner
1,255 Views

Steve,

I tried out your suggestion on my example and it's not a complete fix, but might be close enough.

I turned on bounds checking when compiling subroutine print_array and turned off bounds checking on program zero. If I modify print_array to access array(), the out of bounds access in print_array is caught at run time and nothing is caught for the out of bounds index in the array argument in program zero. 

ifort -traceback -c zero.f90

program zero

  integer,parameter :: array_dim=0
  integer :: array(array_dim)

  array=1
  
  call print_array(array(0),array_dim)

END PROGRAM zero

ifort -check bounds -traceback -c print_array.f90

subroutine print_array(array,size)
  integer :: size,array(size)
  integer :: i
  
  do i=1,size+1
    write(*,*)i,array(i)
  end do
  
end subroutine print_array

ifort zero.o print_array.o -o xzero

./xzero

forrtl: severe (408): fort: (2): Subscript #1 of the array ARRAY has value 1 which is greater than the upper bound of 0

Image              PC                Routine            Line        Source             
xzero              0000000000404060  Unknown               Unknown  Unknown
xzero              00000000004025BB  print_array_                6  print_array.f90
xzero              0000000000402507  MAIN__                      8  zero.f90
xzero              00000000004024AE  Unknown               Unknown  Unknown
libc.so.6          00002B0F912C0AF5  Unknown               Unknown  Unknown
xzero              00000000004023B9  Unknown               Unknown  Unknown

Not a complete fix because in reality my coding for program zero would be much more complex and I would want bounds checking in other parts of that routine, but it is better than nothing. Thanks.

Jobie

0 Kudos
Reply