1

画面に「Finalization」と書き込むだけt_fileのファイナライズルーチンを備えた派生型があります。closeタイプのインスタンスを返す関数もありますt_file。このプログラムの出力は次のとおりです。

Finalization.
Finalization.
Just opened
     2000
Done.

2つの質問があります:

  • 出力のにファイナライズが行われるのはなぜですか?Just opened
  • ファイナライズが2回行われるのはなぜですか?

私のコンパイラはIntel(R)Visual Fortran Composer XE201112.1.3526.2010です。

コードは次のとおりです。

module m_file
    implicit none


    type t_file
        integer::iu=1000

        contains

        final::close
    end type

    contains

    function openFile() result(f)
        implicit none

        type(t_file)::f

        f%iu = 2000

    end function

    subroutine close(this)
        implicit none

        type(t_file)::this

        write(*,*) 'Finalization.'

    end subroutine

end module

program foo
    use m_file
    implicit none

    type(t_file)::f

    f = openFile()
    write(*,*) 'Just opened'
    write(*,*) f%iu

    write(*,*) 'Done.'    
    read(*,*)

end program
4

2 に答える 2

5

この行動には私も驚きました。私は Fortran の新しい (-ish) OO 機能に慣れてきましたが、まだ最終的な手順を書く必要はありません。この振る舞いについて、ある種の説明を提供できると思います。

Modern Fortran Explainedのp282 で、著者は次のように書いています。

ファイナライズ可能なオブジェクトが (たとえば、割り当て解除やreturnステートメントの実行によって) 存在しなくなると、オブジェクトを実引数として final サブルーチンが呼び出されます。これは、オブジェクトがインテント仮引数に渡されたout場合、または組み込み代入ステートメントの左側の変数である場合にも発生します。後者の場合、最後のサブルーチンは、右側の式が評価された後、変数に割り当てられる前に呼び出されます。

この段落で言及した 2 つのケースの両方に当てはまっているように見えます。関数内で名前がFinalization付けられたエンティティが、その関数からの戻り時にスコープ外に出ようとしているときに、最初に取得します。fopenFile

プログラム スコープ内の変数が割り当ての左辺で使用されると、2 番目Finalizationになります。ff = openFile()

以上のことから、プログラムの範囲内で の早期終了が見られるのではなくf、微妙に異なる何かが見られると結論付けます。

これが起こっていることだと完全に確信しているわけではなく、言語の動作がそのままであるべき正当な理由が思いつきません。Finalization調べてみると、プログラムが終了しfて範囲外になったときに3 番目のメッセージが表示されないことに少し驚いています。

運が良ければ、本物の Fortran の第一人者がすぐに現れて、私たち全員を啓蒙してくれるでしょう。

于 2012-06-25T14:17:16.260 に答える
0

High Performance Mark による回答へのマイナーな修正: 最初のファイナライズは、実際にはプログラム スコープ内の変数 f です。これは、最終ルーチンで this%iu を出力し、プログラム スコープで f%iu を任意の値に設定するだけで確認できます。

于 2013-03-05T07:34:43.207 に答える