ホームページ >バックエンド開発 >C++ >最適化が有効な場合、この C コードが GCC で無限ループを生成するのはなぜですか?

最適化が有効な場合、この C コードが GCC で無限ループを生成するのはなぜですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-05 04:47:13796ブラウズ

Why Does This C   Code Produce an Infinite Loop on GCC with Optimizations Enabled?

x86 での整数オーバーフロー: 無限ループの謎を解く

GCC を使用してコンパイルすると、不思議なことに無限ループに突入する次のコード スニペットを考えてみましょう。 :

int i = 0x10000000;
do {
    i += i;
    cout << i << endl;
} while (i > 0);

ミステリーUnraveled

整数オーバーフローは通常未定義の動作ですが、x86 アーキテクチャの整数演算命令はオーバーフローが発生すると通常ラップアラウンドします。ただし、この場合、GCC の最適化によって異常が発生します。

最適化の不幸

最適化が有効になっていると、GCC は整数オーバーフローが不可能であると想定し、ループ終了条件のチェックを排除します。その結果、整数 i が負の値にラップすると、ループが無限に続きます。

Visual Studio の正しい処理

一方、Visual Studio では、整数オーバーフローを正しく処理し、次のようにループを終了します。

未定義の動作の決定

この奇妙な動作は、未定義の動作の予測不可能な性質を浮き彫りにします。 x86 では整数ラップアラウンドが期待されていますが、未定義の動作が予期せぬ形で現れ、コンパイラーの予測を裏切る可能性があります。

回避策

  • 最適化を無効にする (-O0)明示的なオーバーフロー チェックを強制するには、-fwrapv フラグを使用します。
  • 明確に定義されたオーバーフロー セマンティクスを有効にします。ただし、パフォーマンスが低下する可能性があることに注意してください。

結論

未定義の動作が存在する場合にループ終了条件を最適化するという GCC の選択により、混乱が生じます。無限ループ。これは、未定義の動作ルールに違反すると予測できない結果が生じることを思い出させるものであり、x86 プラットフォームで整数演算を使用する場合は注意が必要です。

以上が最適化が有効な場合、この C コードが GCC で無限ループを生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。