C言語の基礎
C言語の規格でいう未定義動作の説明として、正しいものはどれか。
- A規格が何も定めていない動作で、コンパイラはそれが起きないと仮定して最適化してよく、予想しない結果にもなる
- B処理系ごとに結果を決め、その結果を文書に書いておくことが義務付けられている動作
- C実行時に必ず検出され、エラーのメッセージを出してプログラムが止まる動作
答えと解説を見る
正解:A. 規格が何も定めていない動作で、コンパイラはそれが起きないと仮定して最適化してよく、予想しない結果にもなる
未定義動作は、符号付き整数のオーバーフロー、配列の範囲外の参照、NULL ポインタの参照、解放後の使用などのように、規格が何も要求していない動作です。たまたま期待どおりに動くこともありますが、コンパイラは「正しいプログラムでは起きない」と仮定して最適化してよいため、最適化の設定やコンパイラの版を変えただけで結果が変わることがあります。これに対し、int の大きさや char の符号の有無のように、処理系が決めて文書に書く必要があるものを処理系定義の動作といいます。gcc や clang では -fsanitize=undefined を付けると、一部の未定義動作を実行時に検出できます。
- A. 正しい。規格は何も要求しないので、どのような結果になっても規格には反しません。
- B. これは処理系定義の動作の説明です。int の大きさや char の符号の有無が当てはまります。
- C. 規格は検出を求めていません。多くの場合、何も知らせずに誤った結果になります。