Reputation: 65
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 ?
Upvotes: 1
Views: 1470
Reputation: 29381
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
Upvotes: 1