3

モジュール プロシージャ外部プロシージャを組み合わせた次のコード:

module module_dummy

  implicit none

contains

  subroutine foo(a)

    real, intent(inout) :: a(:)

    call bar(a)

  end subroutine foo

end module module_dummy

program main

  use module_dummy

  implicit none 

  integer, parameter :: nelems = 100000000
  real,  allocatable :: a(:)

  allocate( a(nelems) )
  a = 0.0
  call foo(a)
  print *, a(1:10)
  deallocate(a)

end program main

subroutine bar(a)

  implicit none

  real, intent(inout) :: a(:)

  a = 1.0      

end subroutine bar

次のいずれかで失敗するようです:

  1. とともにsegmentation fault
  2. 0.000のブロックの代わりに のブロックを印刷する1.000

これまでに試したどのプラットフォームでも。この問題は の暗黙的なインターフェイス宣言に関連してbarおり、実際には、次のような方法で明示的なインターフェイスを追加することで問題を解決できます。

module module_dummy

  implicit none

contains

  subroutine foo(a)

    interface 
       subroutine bar(x)
         real, intent(inout) :: x(:)
       end subroutine bar
    end interface

    real, intent(inout) :: a(:)

    call bar(a)

  end subroutine foo

end module module_dummy

barまたはモジュール内で使用するように宣言しますmodule_dummy

とにかく、そもそもエラーが何であるかが本当にわかりません。Fortran 90 標準(12.3.2.4 節) で見つけたものは、次のように述べています。

プロシージャーの引用仕様が暗黙的であるスコープ単位から参照されるプロシージャーの仮引数の型、型パラメーター、および形状は、実引数が仮引数の特性と一致するものでなければなりません。

この場合、a常に次のように宣言されているように、ルールは尊重されているようです。

real, intent(inout) :: a(:) 

では、以前のコードを間違った標準の解釈で欠落しているものは何ですか?

4

1 に答える 1

6

仮定された形状であるダミー引数は、その参照点に明示的なインターフェイスを持たなければなりません。F90 12.3.1.1 項目 2c。

実際には、想定形状配列は、記述子 (配列の境界と格納場所を記述する小さな構造体) を渡すことによって渡されます。Ye-olde F77 の明示的な形状と想定サイズの配列は、最初の要素のアドレスを渡すだけで渡されます。明示的なインターフェイスがないと、コンパイラは記述子を作成して渡す必要があることを認識できません。したがって、混乱と混乱が生じます。

于 2012-11-08T20:52:13.783 に答える