Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing assumed-shape arrays in two levels of subroutines (Fortran 90)

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.

like image 788
user630900 Avatar asked Feb 23 '11 19:02

user630900


1 Answers

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.

like image 140
eriktous Avatar answered Nov 15 '22 12:11

eriktous