3

商用プログラムのプログラマーズ マニュアルに公開されているソース コードから、非常に困惑するコード スニペットを分離しました。

以下の関数は、カーネルによって複数回呼び出されることが想定されており、相互接続された多くのコンポーネントで構成されるシステム内のコンポーネントの一時的な動作を実装することになっています (入力/出力パラメーターは関数プロトタイプとは無関係であるため、関数プロトタイプから削除しました)。私が上昇しようとしているポイント)。

同じブロック タイプの異なるインスタンスを区別するために、カーネルは INFO(1) 要素でインスタンス番号を渡します。

私が理解している限りでは、このプログラムの設計者は、呼び出しごとに PAR ベクトルから意味のある名前を持つローカル変数にパラメーターの値をコピーするのに費やされた時間を節約しようと多大な努力をしました (あたかもそうでないかのように)コンパイラが実行できる最適化に注意してください)。最初の呼び出しでのみ、または呼び出し元が同じ型の別のインスタンスに切り替えたときにのみ、それらをローカル変数に割り当てたかったようです。

ただし、ローカル変数が「保存」キーワードで静的に宣言されていない場合、これがどのように機能するか理解できません。FORTRAN はローカル変数を静的に保存しますか、つまりスタックには保存しませんか? (質問が愚かに聞こえる場合は申し訳ありません。私は C/C++ 言語に慣れています)

ありがとうございました。

SUBROUTINE TYPE151(PAR, INFO, *)

    IMPLICIT NONE

    INTEGER*4 INFO(15), IUNIT
    DOUBLE PRECISION PAR, QMAX

    PARAMETER (NP=1)
    DIMENSION PAR(NP)

    ! First call
    IF (INFO(7).EQ.-1) THEN

        IUNIT = INFO(1)

        QMAX = PAR(1)

        RETURN 1
    ENDIF

    ! later calls
    IF(INFO(1).NE.IUNIT) THEN

        IUNIT = INFO(1)

        QMAX = PAR(1)
    ENDIF

    ! Making use of QMAX in some ways...

    RETURN 1 
END SUBROUTINE TYPE151
4

1 に答える 1

4

ストレージ メソッドは、言語標準の一部ではありません。古い FORTRAN コンパイラ (FORTRAN 77 以前) は、多くの場合、すべての変数を静的に格納していました。この言語では、プロシージャの呼び出し間で値を保持する必要がある変数に「SAVE」を使用する必要があります。しかし、多くのプログラマーはこの要件を無視し、FORTRAN 77 時代のコンパイラーの典型的な設計のために、すべての変数が値を保持するという動作に依存していました。

最近の Fortran コンパイラは通常、メモリの使用方法が異なり、SAVE が省略されている場合、プロシージャのローカル変数は常に値を保持するとは限りません。これにより、古いプログラムを現在のコンパイラでコンパイルすると、バグが頻繁に発生します。コンパイラは通常、古い動作を復元するオプションを提供します。そうしないと、宣言に SAVE 属性を追加する必要がある大規模なレガシー プログラム内のすべての変数を特定するのが大変な作業になる可能性があります。

于 2013-03-14T16:43:28.977 に答える