2

私は次のようなFortranコードを持っていました:

 subroutine foo(mx,my,mz)
    real pts(3,mx,my,mz)
 end

配列ptsがサブルーチンで実際に使用されることはありませんでした。コードをリファクタリングしたときに、配列ptsを削除するのを忘れただけです。さて、Fortranにはスタックとヒープの概念がないので、ptsをどこに割り当てるかはコンパイラー次第です-これはgfortranの配列サイズの関数ですが、ポートランドグループコンパイラーがどのように理解することができませんでしたこれを処理します。

ptsがスタック、ヒープに割り当てられているかどうか、または完全に最適化されているかどうか(おそらくそうあるべきです)を判断することは可能ですか?スタックオーバーフローが発生し、それを知らない(つまり、ランタイムエラーが発生しない)可能性はありますか?私の本能は、コンパイラーによって生成されたアセンブリを見ることでわかるはずですが、そこで何を見ているのかわかりません。

4

2 に答える 2

6

最も簡単な方法は、コンパイラーでコンパイルするときにコンパイラーが提供するアセンブリー・コードを-S調べるか、デバッガーでシンボルを探すことです。配列がヒープに割り当てられている場合、おそらく割り当て関数が呼び出されます。

  • gfortranはへの呼び出しを挿入しますmalloc
  • ifortは、デフォルトですべてのアレイをスタックに割り当てます。自動ヒープ配列を有効にすると、ヒープ割り当ての-heap-arrays <size>呼び出しが生成されますfor_alloc
  • PGIコンパイラはへの呼び出しを生成しますpgf90_auto_allocが、このコンパイラと配列の割り当て方法については経験がありません。

ちなみに、gfortranは、デフォルトの最適化レベルでも参照されていない場合、配列を削除します。他のコンパイラも同じことをしていると思いますが、私はそれには賭けません。

于 2012-05-23T20:11:16.230 に答える
3

これは、デッドコードの除去に関連する動作が普遍的ではなく、コンパイラ固有であるだけでなく、ケース固有でもあるという意味で、コンパイラ固有の質問だと思います。最適化がオンになっている最新のコンパイラーは、到達不能コード、またはプログラムの状態に関して何も達成しないコードを確実に排除します。未使用の変数と配列は、最終的な実行可能ファイルにはまったく含まれません。

あなたが言ったように、あなたの最善の策は、コンパイルされたバイナリのアセンブリコードを見て、それが何をするかを見ることです。

于 2012-05-23T19:41:36.963 に答える