Question

I have a rather simple piece of code (reduced to the essentials from bigger program).

I pass an array and the size of the array to a subroutine. I get no error if the passed size does not match the actual size of the array. And I can even manipulate the parts of the array that don't "exist" !!! (I overwrite memory that I shouldn't overwrite).

Here is the subroutine:

subroutine sub(arr, narr)
implicit none
integer, intent(in) :: narr
double precision, dimension(narr) :: arr
integer :: j

do j = 1, narr
  ! print all the values
  write(*, '("Arr[",I0,"] = ",f0.10)') j, arr(j)
  ! change the values
  arr(j) = -10d0
enddo

end subroutine

and here the main program

program main

implicit none

integer, parameter :: narr = 5
! the array is made smaller
double precision, dimension(narr - 2) :: array

integer :: j

! assign values to array
array = (/ (1d0*j,   j = 1,narr - 2) /)

! print using the subroutine
print*, "inside subroutine" 
call sub(array, narr)

! print outside the subroutine
print *, " "
print *, "outside subroutine"
do j = 1, narr
  write(*, '("Arr[",I0,"] = ",f0.10)') j, array(j)
enddo

end program

If I compile with ifort and "-check all" it only catches the error in the main program, but not in the subroutine.

Is there a way to catch also the error in the subroutine ?

Was it helpful?

Solution

Yes. Declare array as dimension(:) in the subroutine -- assumed-shape array. Using this Fortran >90 declaration requires that the procedure interface be known to the caller -- the easiest way is to have the procedure in a module and use that module in the caller. You don't actually need to pass the size of the array to the subroutine -- you can determine it as size(arr). I have left the argument narr to retain the bug.

module MySub

contains

subroutine sub(arr, narr)
implicit none
integer, intent(in) :: narr
double precision, dimension(:) :: arr
integer :: j

do j = 1, narr
  ! print all the values
  write(*, '("Arr[",I0,"] = ",f0.10)') j, arr(j)
  ! change the values
  arr(j) = -10d0
enddo

end subroutine

end module MySub


program main

use MySub

implicit none

integer, parameter :: narr = 5
! the array is made smaller
double precision, dimension(narr - 2) :: array

integer :: j

! assign values to array
array = (/ (1d0*j,   j = 1,narr - 2) /)

! print using the subroutine
print*, "inside subroutine"
call sub(array,narr)

! print outside the subroutine
print *, " "
print *, "outside subroutine"
do j = 1, narr
  write(*, '("Arr[",I0,"] = ",f0.10)') j, array(j)
enddo

end program
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top