I have had problems calling successive subroutines with assumed-shape arrays in Fortran 90. More specifically, I call two levels of subroutines, passing an assumed-shape array as a parameter, but in the end the array is lost. To demonstrate it, one can follow the code below.
program main
INTERFACE
subroutine sub1(x)
real, dimension(:):: x
real C
end subroutine sub1
subroutine sub2(x)
real, dimension(:):: x
real C
end subroutine sub2
END INTERFACE
real, dimension(:), allocatable:: x
allocate(x(1:10)) ! First executable command in main
x(1) = 5.
call sub1(x)
write(*,*) 'result = ',x(1)
deallocate(x)
end program main
subroutine sub1(x) ! The first subroutine
real, dimension(:):: x
real C
call sub2(x)
end subroutine sub1
subroutine sub2(x) ! The second subroutine
real, dimension(:):: x
real C
C2=x(1)
end subroutine sub2
Very shortly, main allocates x then call sub1(x). Then sub1 calls sub2(x). That means an allocated array is passed to a subroutine that passes it to another subroutine. I would expect to have in sub2 the same array that I've created in main, but no. Using gdb as a tool to explore it, I get this:
1) In main, just before calling sub1, the array x is perfectly defined:
(gdb) p x
$1 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2) Within sub1, just before calling sub2, x is also well defined:
(gdb) p x
$2 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)
3) Inside sub2, however, x have an unexpected value and even its dimension is absolutely wrong:
(gdb) p x
$3 = ()
(gdb) whatis x
type = REAL(4) (0:-1)
So, x has been successfully passed from main to sub1, but not from sub1 to sub2. I've been using Intel Fortran an gfortran with the same results.
I've struggling with that for a long time. Any help would be much appreciated.
G.Oliveira.
The use of assumed-shape dummy arguments requires an explicit interface.
In your main program you've provided explicit interfaces for the two subroutines, but these don't propagate into the subroutines themselves. The subroutines are compiled as separate units, even if you've put all your code into one source file.
This means that sub1 doesn't have an explicit interface available for sub2, and thus uses an implicit interface, where the argument x is assumed to be a real scalar.
All this could be avoided simply by putting the two subroutines in a module and use
that module in your main program, automatically making explicit interfaces available. This way you don't have to provide the interfaces yourself, which is error prone.
As a side note, I advise the use of implicit none in ALL your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With