コンパイラ

C言語で、符号付き整数のオーバーフローは未定義動作である。この前提で、上の関数を最適化するコンパイラが生成しうるコードとして正しいものはどれか。

int f(int x) {
    return x + 1 > x;
}
  1. Ax が最大値のときだけ0を返すよう、比較の命令を必ず残す
  2. B常に1を返すコードに置き換える
  3. C未定義動作を含むので、コンパイルを中止してエラーにする
答えと解説を見る

正解:B. 常に1を返すコードに置き換える

符号付き整数のオーバーフローは未定義動作なので、コンパイラは「正しいプログラムではオーバーフローは起きない」と仮定してよいことになっています。その仮定のもとでは x + 1 は常に x より大きいので、比較を省いて常に1を返すコードにできます。x が最大値のときに0を期待するコードは、この最適化で期待どおりに動かなくなることがあります。未定義動作は多くの場合コンパイル時には検出されず、エラーにはなりません。

  • A. オーバーフローしない前提なので、比較を残す必要はありません。
  • B. 正しい。オーバーフローしない前提で、常に真と判断できます。
  • C. 未定義動作は多くの場合、コンパイル時のエラーにはなりません。
この分野を解く 分野ページへ

コンパイラのほかの問題

  1. プログラムの誤りのうち、コンパイルの時点で見つけることができるものはどれか。
  2. 静的な型をもつ言語で、コンパイラが型検査を行う主な利点はどれか。
  3. 字句解析でトークンを見分ける規則を表すのによく使われるものはどれか。
  4. 多くのプログラミング言語の文法を表すのに使われ、構文解析の基礎になる文法の種類はどれか。
  5. 式 2 + 3 * 4 の抽象構文木の形として正しいものはどれか。