5

我在 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) 像素
$1 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)

2) 在 sub1 中,就在调用 sub2 之前,x 也是很好定义的:

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

3) 然而,在 sub2 内部,x 有一个意想不到的值,甚至它的维度也是绝对错误的:

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

因此,x 已成功从 main 传递到 sub1,但没有从 sub1 传递到 sub2。我一直在使用 Intel Fortran 和 gfortran,结果相同。

我已经为此苦苦挣扎了很长时间。任何帮助将非常感激。
G.奥利维拉。

4

1 回答 1

11

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

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

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

于 2011-02-24T12:25:01.703 回答