Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking the size of an array passed to a function

Tags:

fortran

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
like image 270
InsideLoop Avatar asked Jun 28 '19 15:06

InsideLoop


People also ask

How do you get the size of an array passed to a function?

The cout statement inside main prints 40, and cout in findSize prints 8. The reason is, arrays are always passed pointers in functions, i.e., findSize(int arr[]) and findSize(int *arr) mean exactly same thing. Therefore the cout statement inside findSize() prints the size of a pointer.

How do you find the size of an array?

To determine the size of your array in bytes, you can use the sizeof operator: int a[17]; size_t n = sizeof(a); On my computer, ints are 4 bytes long, so n is 68. To determine the number of elements in the array, we can divide the total size of the array by the size of the array element.

Can the sizeof operator be used to tell the size of an array passed to a function?

Can the sizeof operator be used to tell the size of an array passed to a function? No. There�s no way to tell, at runtime, how many elements are in an array parameter just by looking at the array parameter itself. Remember, passing an array to a function is exactly the same as passing a pointer to the first element.


Video Answer


2 Answers

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

like image 170
PTRK Avatar answered Nov 15 '22 18:11

PTRK


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.

like image 28
francescalus Avatar answered Nov 15 '22 18:11

francescalus