Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.
29306 Discussions

Bounds checking, zero sized array and sequence association

Jobie_G_
Beginner
1,315 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,315 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,315 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