スタック: 自動割り当てと確認

このグループのオプションは、コンパイラにより生成されたコードのスタックおよび変数の計算を制御できます。

変数の自動割り当て

-auto

-auto オプションは、ローカルで宣言された変数を、スタティック・ストレージではなくランタイム・スタックに割り当てるよう指定します。プロシージャで定義された変数が SAVE または ALLOCATABLE 属性を持たない場合、それらの変数は、スタックのみに割り当てられます。このオプションは、EQUIVALENCE 文または SAVE 文内の変数、および COMMON 内の変数には作用しません。

-auto の機能は、-automatic および -nosave と同じです。

-auto を指定すると、プログラムのパフォーマンスが向上することがあります。 ただし、プログラムが、最後にルーチンが呼び出されたときと同じ値を持つ変数に依存している場合は、プログラムが正しく機能しないことがあります。複数のルーチン呼び出しにわたってその値を保持する必要のある変数は、SAVE 文内になければなりません。

-recursive または -openmp を指定した場合、デフォルトで -auto が使用されます。

-auto_scalar:

-auto_scalar オプションにより、INTEGERREALCOMPLEX、または LOGICAL の各組込み型ローカルスカラ変数のスタックへの割り当てが行われます。このオプションは、EQUIVALENCE 文または SAVE 文内の変数、および COMMON 内の変数には影響しません。

-auto_scalar を指定すると、プログラムのパフォーマンスが向上することがあります。 ただし、プログラムが、最後にルーチンが呼び出されたときと同じ値を持つ変数に依存している場合は、プログラムが正しく機能しないことがあります。複数のサブルーチン呼び出しにわたってその値を保持する必要のある変数は、SAVE 文内になければなりません。このオプションは、すべてのローカル変数をスタックに割り当てる -auto によく似ていますが、 -auto_scalar は上記の型のスカラ変数のみをスタックに割り当てる点が異なります。

 -auto_scalar を指定すると、コンパイラは、プログラムの実行中にどの変数をレジスタに保持すべきかについて、より良い選択が行えます。

-save, -zero

-save オプションは -auto オプションと逆の効果が得られます。-save オプションは、再帰ルーチン内にあるローカル変数を除くすべての変数を静的割り当てに保存します。ルーチンが 2 回以上呼び出される場合は、このオプションを指定すると、最後に終了した呼び出しから得られるローカル変数の値が保持されます。-save オプションにより、ルーチンの終了時に最終結果がメモリに保存され、次回の呼び出しの際に再利用されます。このオプションでは、結果の丸めが頻繁になるので、一部パフォーマンスが低下することがあります。

コンパイラがコードを最適化する際、結果はレジスタに保存されます。-save の機能は -noauto と同じです。

-zero[-] オプションは、INTEGERREALCOMPLEX、または LOGICAL 組込み型のローカルスカラ変数で、保存はされているがまだ初期化されていない変数を、すべてゼロに初期化します。-save とともに使用されます。デフォルトは、-zero-です

まとめ

変数を割り当てるには、 -save-auto-auto_scalar の 3 つの方法があります。指定できるのはこれらのうち 1 つだけです。各方法は次のような相互関係にあります:

浮動小数点スタックの状態のチェック (IA-32 のみ) (-fpstkchk)

IA-32 専用の -fpstkchk オプションは、プログラムが浮動小数点値を返す関数への呼び出しを正しく行っているかどうかをチェックします。不正な呼び出しが検出されると、このオプションがプログラムに不正な呼び出しをマークするコードを追加します。

アプリケーションが浮動小数点値を返す関数を呼び出すと、返された浮動小数点値は通常、浮動小数点スタックの最上位に保存されます。戻り値が使用されない場合、コンパイラは浮動小数点スタックを正しい状態に保つため、浮動小数点スタックから値をポップします。

アプリケーションが関数のプロトタイプを定義しなかったり、誤ったプロトタイプを定義して関数を呼び出すと、その関数が浮動小数点値を返す必要があるかどうかをコンパイラが判断できず、戻り値が使用されない場合に浮動小数点スタックからその値がポップされません。この場合には、浮動小数点スタックがオーバーフローする可能性があります。

スタックのオーバーフローにより、次のような好ましくない事態が発生します:

-fpstkchk オプションは、不正な呼び出しにマークを付けてエラーを検出しやすくします。

このオプションは、各関数/サブルーチン呼び出しの後で大量のコードを生成して浮動小数点スタックを正しい状態に維持しますが、コンパイル処理の速度は低下します。デバッグの際に浮動小数点スタックのアンダーフローやオーバーフローの問題を検出するためにのみ使用してください。これらの問題はこのオプションを使用しないと検出するのが困難です

別名

-common_args

-common_args オプションは、「参照による」サブプログラム引数がお互いの別名を持っているとみなします。

CRAY* ポインタ・エイリアシングを回避する

オプション -safe_cray_ptr は、CRAY* ポインタが他の変数とエイリアスしないように指定します。デフォルトはオフです。

次の例について考えてみます。

pointer (pb, b)
pb = getstorage()
do i = 1, n
b(i) = a(i) + 1
enddo

-safe_cray_ptr オプションが指定されない場合 (デフォルト)、コンパイラは、ba がエイリアスされていると仮定します。 このような仮定を回避するには、このオプションを指定します。コンパイラは b(i)a(i) がお互いに独立しているとして処理します。

しかし、変数を CRAY ポインタとエイリアスする場合、-safe_cray_ptr オプションを使用すると、正しい結果が得られません。下記の例のようなコードでは、-safe_cray_ptr オプションを使用しないでください。

pb = loc(a(2))
do i=1, n
b(i) = a(i) +1
enddo

-ansi_alias

-ansi_alias[-] が有効 (デフォルト) に設定されている場合、コンパイラはプログラムが ANSI Fortran 型のエイリアス規則に準拠していると仮定します。例えば、real 型のオブジェクトは、integer としてアクセスできません。詳しい規則については、ANSI 標準を参照してください。

このオプションは、次の点を前提にしてコンパイラに指示します。

プログラムが上記の条件を満たす場合、-ansi_alias フラグを設定することでプログラムの最適化が向上します。ただし、プログラムが上記の条件を 1 つでも満たさない場合、コンパイラは誤ったコードを生成する可能性があるため、このオプションを無効にしなければなりません。

-ansi_alias のシノニムは、-assume [no]dummy_aliases です。