2016-04-27 20 views
2

Fortranモジュールで循環依存性がどのように正確に解決されたかわかりません。以下のモジュールはFortranモジュールの型間の循環依存性

module types 
    implicit none 
    type type1 
     type(type2), pointer :: t2 
    end type type1 

    type type2 
     type(type1)   :: t1 
     integer    :: x 
    end type type2 
end module 

のifort-2016とのgfortran-4.9でコンパイルが、私は

module types 
    implicit none 
    type type2 
     type(type1)   :: t1 
     integer    :: x 
    end type type2 

    type type1 
     type(type2), pointer :: t2 
    end type type1 
end module 

に定義の順序を変更する場合、私は次のようなエラー

error #6457: This derived type name has not been declared. [TYPE1] 
     type(type1)   :: t1 

は行動がある取得しますifort-2016およびgfortran-4.9と同じです。 両方のモジュールで同様の循環依存関係が存在するので、最初のコンパイルはなぜコンパイルされますが、2番目のコンパイルはなぜですか?

答えて

3

作業コードと非作業コードの違いは、コンポーネントの属性がpointerのタイプの場所です。これは、以前に定義されていない型を型宣言が参照できるようにするこの属性です。ここで

type type2 
    type(type1)   :: t1 
    integer    :: x 
end type type2 

ルックタイプtype2type1コンポーネントはpointer属性をしていません。これは、タイプtype1が以前に定義されていなければならないことを意味します。あなたの最初の、実際の例では、その例です。あなたの第二の、壊れた、例では、そうではありません。

type2コンポーネントは、ポインタ属性を持つ他のタイプ

type type1 
    type(type2), pointer :: t2 
end type type1 

を見てみます。したがって、タイプtype2はこの参照の前に定義される必要はありません。どちらの例でもこれが実際に見えます。

この要件は、POINTERもALLOCATABLE属性も指定されていない場合、コンポーネント-DEF-のstmtで宣言型-specが指定するものと

C440(R436)としてのFortran 2008標準に記載されています内在型または先に定義された派生型。


私はpointer属性に、ここで注意を制限してきました。見積もりの​​ように、allocatable属性でも同じことが言えます。 allocatableでこの後の参照を許可することは、Fortran 2008の新機能です。Fortran 2003ではpointer属性が必要でした。 Vladimir Fがコメントしているように、この新しい自由(再帰的に割り当て可能なコンポーネントを提供する)はすべてのコンパイラで実装されていません。上記の「pointer」または「allocatable」を適宜読みます。

+0

多くのコンパイラは、C440でALLOCATABLE、POINTERのみの例外を実装していません。 –

+0

良い点。私は(間違って) 'allocatable'はF2008では再帰的定義のためだけに新しくなったと考えてきましたが、これは"以前に定義された "の具体例です。 F2003では、このような場合には一般的に「ポインタ」しか許されていなかった。 – francescalus