予期しない無限ループ出力: C コンパイルの落とし穴
C では、次のように一見無害に見える特定の操作が予期しない動作を引き起こす可能性があります。次のコード スニペット:
<code class="cpp">#include <iostream> #include <complex> using namespace std; int main() { complex<int> delta; complex<int> mc[4] = {0}; for (int di = 0; di < 4; di++, delta = mc[di]) { cout << di << endl; } return 0; }</code>
「0、1、2、3」という予想される出力に反して、コードは誤って無限の一連の数値を生成します。この不可解な動作は、未定義の動作に関連する微妙だが重大な問題から生じています。
未定義の動作の難問
代入ステートメント delta = mc[di] は mc 配列にアクセスします。ループの最後の反復で有効なインデックスを超えています。 C の領域では、境界外のメモリへのアクセスは未定義の動作を構成し、予測不可能な結果が支配する領域となります。
積極的なループ最適化: 諸刃の剣
コンパイラは、パフォーマンスを向上させるために積極的なループ最適化を採用することがよくあります。これらの最適化は、未定義の動作が存在しないという仮定を利用します。指定されたコードの場合、コンパイラーは di
謎の解明
最適化が有効で -fno-aggressive なしの GCC -loop-optimizations フラグは、無限ループ動作を示します。ただし、そのフラグを有効にすると、誤った動作はなくなります。アセンブリ コードを調べると、di
落とし穴の回避
このような落とし穴を防ぐには、未定義の動作を避け、明示的にチェックすることが重要です。配列の境界。さらに、警告フラグを通じて適切な診断メッセージを確実に提供することで、潜在的な問題について貴重な洞察を得ることができます。
結論
未定義の動作は、C コードで予期しない予測できない動作を引き起こす可能性があります。このような潜在的な落とし穴を認識し、予期せぬ結果を防ぐために健全なプログラミングの実践に熱心に従うことが重要です。
以上がこの C コードが単純な出力ではなく無限ループになるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。