C言語の基礎

C言語の規格でいう未定義動作の説明として、正しいものはどれか。

  1. A規格が何も定めていない動作で、コンパイラはそれが起きないと仮定して最適化してよく、予想しない結果にもなる
  2. B処理系ごとに結果を決め、その結果を文書に書いておくことが義務付けられている動作
  3. C実行時に必ず検出され、エラーのメッセージを出してプログラムが止まる動作
答えと解説を見る

正解:A. 規格が何も定めていない動作で、コンパイラはそれが起きないと仮定して最適化してよく、予想しない結果にもなる

未定義動作は、符号付き整数のオーバーフロー、配列の範囲外の参照、NULL ポインタの参照、解放後の使用などのように、規格が何も要求していない動作です。たまたま期待どおりに動くこともありますが、コンパイラは「正しいプログラムでは起きない」と仮定して最適化してよいため、最適化の設定やコンパイラの版を変えただけで結果が変わることがあります。これに対し、int の大きさや char の符号の有無のように、処理系が決めて文書に書く必要があるものを処理系定義の動作といいます。gcc や clang では -fsanitize=undefined を付けると、一部の未定義動作を実行時に検出できます。

  • A. 正しい。規格は何も要求しないので、どのような結果になっても規格には反しません。
  • B. これは処理系定義の動作の説明です。int の大きさや char の符号の有無が当てはまります。
  • C. 規格は検出を求めていません。多くの場合、何も知らせずに誤った結果になります。
この分野を解く 分野ページへ

C言語の基礎の参考書を探す PR

Amazonの検索結果へのリンクです。Amazonのアソシエイトとして、半導体教室は適格販売により収入を得ています。

C言語の基礎のほかの問題

  1. int と unsigned int は32ビットとする。次のうち、C言語の規格で未定義動作になるものはどれか。
  2. 上の関数を gcc で最適化を有効にしてコンパイルすると、if (p == NULL) の判定が削除されることがある。その理由として正しいものはどれか。
  3. C言語の規格で、int型の大きさについて定められていることとして、正しいものはどれか。
  4. 組込みのプログラムで、32ビットの周辺レジスタの値を入れる変数を、unsigned int ではなく stdint.h の uint32_t で宣言することが多い。主な理由として正しいものはどれか。
  5. 整数どうしの割り算を含む上のコードを実行したときの出力として、正しいものはどれか。