コンパイラ
C言語で、符号付き整数のオーバーフローは未定義動作である。この前提で、上の関数を最適化するコンパイラが生成しうるコードとして正しいものはどれか。
int f(int x) {
return x + 1 > x;
}
- Ax が最大値のときだけ0を返すよう、比較の命令を必ず残す
- B常に1を返すコードに置き換える
- C未定義動作を含むので、コンパイルを中止してエラーにする
答えと解説を見る
正解:B. 常に1を返すコードに置き換える
符号付き整数のオーバーフローは未定義動作なので、コンパイラは「正しいプログラムではオーバーフローは起きない」と仮定してよいことになっています。その仮定のもとでは x + 1 は常に x より大きいので、比較を省いて常に1を返すコードにできます。x が最大値のときに0を期待するコードは、この最適化で期待どおりに動かなくなることがあります。未定義動作は多くの場合コンパイル時には検出されず、エラーにはなりません。
- A. オーバーフローしない前提なので、比較を残す必要はありません。
- B. 正しい。オーバーフローしない前提で、常に真と判断できます。
- C. 未定義動作は多くの場合、コンパイル時のエラーにはなりません。