Stand With Ukraine

Saturday, September 11, 2010

Fortran 90 pass subroutine as an argument to the other subroutine

In fortran 90 it is not enough to just declare(unless the passed function has parameters):
subroutine caller(arg, called)
integer :: arg
external :: called
call called(arg)
end subroutine caller
view raw func_as_par.f hosted with ❤ by GitHub


as it is in fortran 77. It actually compiles by pgf90 but does not run (worked for the function which did not take any arguments).
You should actually include interface description for it to work in f90:
subroutine caller(arg, called)
integer :: arg
interface
subroutine called(arg)
integer :: arg
end subroutine called
end interface
call called(arg)
end subroutine caller


Update: This appeared also to be the case when passing to a subrouting allocatable array which is supposed to be initialized inside the subroutine. And also, as I understood from the posts of smart people, it is not necessary to describe the interface of the called subroutine if it is declared inside a module.
Below is the example of a subroutine parameter which has an allocatable array as one of the arguments:
program main
implicit none
interface
subroutine to_be_called(arg, nx, ny, arr)
integer :: arg, nx, ny
integer, allocatable, intent(out) :: arr(:, :)
end subroutine to_be_called
end interface
print *, "Hello"
call caller(5, to_be_called)
end program main
subroutine to_be_called(iarg, nx, ny, arr)
integer :: iarg, nx, ny
integer, allocatable, intent(out) :: arr(:, :)
allocate (arr(nx, ny))
arr = iarg
end subroutine to_be_called
subroutine caller(arg, called)
integer :: arg
interface
subroutine called(arg, nx, ny, arr)
integer :: arg, nx, ny
integer, allocatable, intent(out) :: arr(:, :)
end subroutine called
end interface
integer :: nx, ny
integer, allocatable :: arr(:, :)
nx = 5;
ny = 5;
call called(arg, nx, ny, arr)
print *, size(arr)
print *, arr
end subroutine caller