5

Fortran 90 で形状引き継ぎ配列を使用してサブルーチンを連続して呼び出すときに問題がありました。具体的には、形状引き継ぎ配列をパラメーターとして渡して 2 つのレベルのサブルーチンを呼び出しましたが、最終的に配列が失われました。それを実証するために、以下のコードに従うことができます。

  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) を呼び出します。つまり、割り当てられた配列が別のサブルーチンに渡されるサブルーチンに渡されます。main で作成したのと同じ配列が sub2 にあると予想されますが、そうではありません。gdb をツールとして使用して探索すると、次のようになります。

1) main では、sub1 を呼び出す直前に、配列 x が完全に定義されています。

(gdb) px
$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

想定形状のダミー引数を使用するには、明示的なインターフェイスが必要です。メインプログラムでは、2つのサブルーチンに明示的なインターフェイスを提供しましたが、これらはサブルーチン自体には伝播しません。すべてのコードを1つのソースファイルに入れた場合でも、サブルーチンは個別のユニットとしてコンパイルされます。
これは、sub1にはsub2で使用できる明示的なインターフェイスがないため、引数xが実際のスカラーであると想定される暗黙的なインターフェイスを使用することを意味します。

これはすべて、2つのサブルーチンをモジュールに配置し、useそのモジュールをメインプログラムに配置して、明示的なインターフェイスを自動的に使用可能にすることで回避できます。このように、エラーが発生しやすいインターフェースを自分で提供する必要はありません。

補足として、すべてのコードで暗黙的なnoneを使用することをお勧めします。

于 2011-02-24T12:25:01.703 に答える