在两级子程序中传递假定形状数组(Fortran 90)

时间:2011-02-23 19:46:03

标签: arrays fortran fortran90

我在使用Fortran 90中的假定形状数组调用连续子程序时遇到了问题。更具体地说,我调用两个级别的子程序,将假定形状的数组作为参数传递,但最后数组丢失了。为了演示它,可以遵循以下代码。

  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

很快,main分配x然后调用sub1(x)。然后sub1调用sub2(x)。这意味着将已分配的数组传递给子例程,该子例程将其传递给另一个子例程。我希望在sub2中有我在main中创建的相同数组,但没有。使用gdb作为探索它的工具,我得到了这个:

1)在main中,就在调用sub1之前,数组x是完美定义的:

(gdb)p x
$ 1 =(5,0,0,0,0,0,0,0,0,0)

2)在sub1中,在调用sub2之前,x也被很好地定义:

(gdb)p x
$ 2 =(5,0,0,0,0,0,0,0,0,0)

3)然而,在sub2中,x具有意外的值,甚至其尺寸也是绝对错误的:

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

因此,x已成功从main传递到sub1,但不是从sub1传递到sub2。我一直在使用英特尔Fortran和gfortran,结果相同。

我很长时间都在努力。任何帮助将不胜感激。
G.Oliveira。

1 个答案:

答案 0 :(得分:10)

使用假定形状的伪参数需要显式接口。 在主程序中,您为这两个子程序提供了显式接口,但这些接口不会传播到子程序本身。即使您已将所有代码放入一个源文件中,子例程也会编译为单独的单元 这意味着sub1没有可用于sub2的显式接口,因此使用隐式接口,其中参数x被假定为真正的标量。

只需将两个子程序放在一个模块中,并在主程序中use该模块,自动生成显式接口,就可以避免所有这些。这样您就不必自己提供接口,这很容易出错。

作为旁注,我建议在所有代码中使用隐式无。