Passing arrays of intended forms in two levels of routines (Fortran 90)

I am having trouble calling sequential routines with arrays of supposed forms in Fortran 90. In particular, I call two levels of routines, passing an array of the intended form as a parameter, but at the end the array is lost. To demonstrate this, you 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 

In the near future, main allocates x, and then calls sub1 (x). Sub1 then calls sub2 (x). This means that the allocated array is passed to the subroutine, which passes it to another subroutine. I would expect to have in sub2 the same array that I basically created, but no. Using gdb as a tool to learn it, I get the following:

1) Basically, just before sub1 is called, the array x is well defined:

(gdb) px
$ 1 = (5,0,0,0,0,0,0,0,0,0,0,0,0)

2) Within sub1, just before sub2 is called, x is also well defined:

(gdb) px
$ 2 = (5,0,0,0,0,0,0,0,0,0,0,0,0)

3) Inside sub2, however, x has an unexpected value and even its dimension is absolutely incorrect:

(gdb) px
$ 3 = ()
(gdb) whatis x
type = REAL (4) (0: -1)

So, x successfully passed from the main to sub1, but not from sub1 to sub2. I used Intel Fortran gfortran with the same results.

I struggled with this for a long time. Any help would be greatly appreciated.
G. oliveira.

+4
source share
1 answer

Using arguments of the fictitious form of the intended form requires an explicit interface. In your main program, you have provided explicit interfaces for the two routines, but they do not apply to the routines themselves. Subprograms are compiled as separate blocks, even if you put all your code in one source file.
This means that sub1 does not have an explicit interface available to sub2, and therefore uses an implicit interface where the argument x is considered to be a real scalar.

All this could be avoided simply by placing two subroutines in the module and use this module in your main program, automatically creating accessible explicit interfaces. Thus, you do not need to provide the interfaces themselves that are error prone.

As a side note, I suggest using implicit none of ALL of your codes.

+10
source

Source: https://habr.com/ru/post/1341031/


All Articles