How to pass allocatable arrays to subroutines in Fortran
If a procedure has a dummy argument that is an allocatable, then an explicit interface is required in any calling scope.
(There are numerous things that require an explicit interface, an allocatable dummy is but one.)
You can provide that explicit interface yourself by putting an interface block for your subroutine inside the main program. An alternative and far, far, far better option is to put the subroutine inside a module and then USE that module in the main program - the explicit interface is then automatically created. There is an example of this on the eng-tips site that you provided a link to - see the post by xwb.
Note that it only makes sense for a dummy argument to have the allocatable attribute if you are going to do something related to its allocation status - query its status, reallocate it, deallocate it, etc.
Please also note that your allocatable dummy argument array
is declared with intent(in)
, which means its allocation status will be that of the associated actual argument (and it may not be changed during the procedure). The actual argument passed to your subroutine may be unallocated and therefore illegal to reference, even with an explicit interface. The compiler will not know this and the behaviour of inquiries like size
is undefined in such cases.
Hence, you first have to check the allocation status of array
with allocated(array)
before referencing its contents. I would further suggest to implement loops over the full array with lbound
and ubound
, since in general you can't be sure about array
's bounds:
subroutine subtest(array) double precision, allocatable, intent(in) :: array(:,:) integer :: iii, jjj if(allocated(array)) then print*, size(array, 1), size(array, 2) do iii = lbound(array, 1), ubound(array, 1) do jjj = lbound(array, 2), ubound(array, 2) print*, array(iii,jjj) enddo enddo endif end subroutine
This is a simple example that uses allocatable dummy arguments with a module.
module arrayMod real,dimension(:,:),allocatable :: theArray end module arrayModprogram test use arrayMod implicit none interface subroutine arraySub end subroutine arraySub end interface write(*,*) allocated(theArray) call arraySub write(*,*) allocated(theArray) end program testsubroutine arraySub use arrayMod write(*,*) 'Inside arraySub()' allocate(theArray(3,2))end subroutine arraySub