2

アプリケーションをデバッグするときに、すべてのコンパイラの最適化をオフにする必要がある/推奨されるのはなぜですか?デバッグビルドでコンパイラの最適化が有効になっているとどうなりますか?

背景

Iは、割込みサービス・ルーチン+ ROM領域/ウインドウ(CONSTグローバル変数)+コードの15K使用可能なコードメモリ空間を有する8ビットマイクロコントローラ(OKI 411)に働いています。 〜13Kをほぼ食べるので、デバッグ中でも最大の最適化を有効にすることが非常に魅力的です。

答えて

6

デバッグバイナリをコンパイルするとき、コンパイラは、コードステートメント(またはコードステートメント)とアセンブリ言語命令との1対1対応を維持しようとします。このようにして、デバッグ中は、命令ごとに命令を進めることができ、デバッガがバイナリ内の現在の位置と正しいソースコードを簡単に関連付けることができます。通常、コンパイラは、すべての名前付き変数がメモリ内のどこかに実際に存在するようにして、デバッガでその内容を表示できるようにします。

コンパイラの最適化により、未使用または不要なローカル変数が削除され、コードが効率的に再構築される場合があります。関数はインライン化され、式は部分的または完全に事前計算または再配置されてもよい。これらのや類似の最適化のほとんどは、元のソースコードを生成されたアセンブリと関連付けるのを困難にします。

1

私が考えることができるのは、デバッグがより困難になる可能性があるということだけです。

それ以外は問題ありません。

2

これをオンにしても問題ありません。コンパイルが速くなるため、通常はオフになっています。これは、大きなプロジェクトでは本当の問題になる可能性があります。可能であれば、それをオンにする方が実際には良いので、最後の最適化のために厄介な問題に遭遇することはありません。

あなたのケースでは、私は確かにそれをオンにします。

これは、特定の形式のデバッグで問題を引き起こす可能性がありますが、そのような場合はオフにする必要があります。

5

を考えてみましょう:最適化の後

for (i = 0; i < 10; i++) { 
    src[i] = dest[i]; 
} 

を、このコードは次のようになります。つまり

src[0] = dest[0]; 
src[1] = dest[1]; 
⋮ 
src[9] = dest[9]; 

、何iはもうありません。デバッガは、iがスタックフレーム上にあると予想しますが、オプティマイザはそれを削除しました。

また、ステッピングすると、PCがどこにでも(ランダムに見かけ上)ジャンプし、デバッグを非常に困難または不可能にするさまざまな奇妙な問題が発生します(オプティマイザの処理内容によって異なります)。

2

私はハードウェアレジスタから読み込もうとしていた同様の状況に遭遇しましたが、レジスタはメモリマップされていました。そしてgccのCFLAGS = " - o2"で間違った値を与えました。CFLAGS = " - O0"の場合、作業が開始されました。コンパイラの最適化がバイパスされるように、揮発性変数にキャストすることで同じ結果が得られることに言及する価値があります。

関連する問題