私はちょうど学校でCを学び始めています、私は基本的な概念を保持しようとしています。これは常にtrueですか?
私たちの宿題は、すべてのint x: x+1 > x
ため
がfalseの場合、真と反例場合推論を与え、真か偽かどうかを判断し、疑問を持っています。
int型が32ビットであり、基本的に整数がバイナリ形式であることを教えてくれたので、私は混乱しています。 x + 1は1の小数点に1を加えますか?
私はちょうど学校でCを学び始めています、私は基本的な概念を保持しようとしています。これは常にtrueですか?
私たちの宿題は、すべてのint x: x+1 > x
ため
がfalseの場合、真と反例場合推論を与え、真か偽かどうかを判断し、疑問を持っています。
int型が32ビットであり、基本的に整数がバイナリ形式であることを教えてくれたので、私は混乱しています。 x + 1は1の小数点に1を加えますか?
x + 1 > x
はINT_MAX + 1
がオーバーフローであり、したがってx + 1 > x
発現はINT_MAX
のx
値は未定義の動作値INT_MAX
を除いてすべてのint
値に対して1
です。
これは実際には、コンパイラが表現を最適化する権利を有することを意味する:
1
によって
x + 1 > x
INT_MAX + 1
は未定義の動作であるため、コンパイラは、この特定のためにそれを言う権利があります>
の式INT_MAX + 1
は> INT_MAX
です。
x == INT_MAX
の式が未定義の動作であるため、x + 1 > x
が偽(0
)の場合もありません。
x
がの代わりにunsigned int
と宣言された場合、状況はまったく異なることに注意してください。 unsigned int
オペランドはオーバーフローすることはありません(ラップアラウンド)。UINT_MAX + 1 == 0
、したがってx + 1 > x
は、x == UINT_MAX
の場合は0
であり、その他の場合はの値の場合は1
です。
現代のコンパイラ(gcc
など)は通常、この式を最適化して1
に置き換える機会を得ます。レコードの
、のようなコードを使用して、既知のサーバープログラムといくつかの深刻なセキュリティ上の問題があった:
if (ptr + offset < ptr)
コードが安全条件をトリガするために意図されましたが、コンパイラは交換することにより(if
声明を出し最適化します0
の式)、攻撃者はサーバープログラムで権限昇格を得ることができました(私が正しく覚えておけば悪用可能なバッファオーバーフローの可能性を開くことによって)。
INT_MAX + 1はINT_MINであることが保証されていますか? – vroomfondel
@rogaos 'INT_MAX + 1'は未定義の動作を呼び出します。通常は* INT_MINになりますが、これはどのような仕様でも保証されません。 – cdhowie
@rogaosええ、何?オーバーフローした場合、UBを呼び出します。それは何かであることは保証されていませんが、実際にはおそらく 'INT_MIN'になります。 –
私はあなたに答えを渡したくないので、正しい軌道に乗るべき質問を返信します。
x
が32ビット符号付き整数に格納できる最大値の場合、x + 1
とは何ですか? (2,147,483,647)
x
(あなたの頭の中で)に値を与えてください。今、2としましょう:
```(2 + 1) > 2```
本当ですか、偽ですか?そして、xの他の値については?
整数が32ビットで格納されている場合、xに1を加算すると(x + 1 < x)になることはありますか?
はい、X + 1は1
の小数点以下の値に追加されますこれは、ほぼすべての時間の中でtrueになります。しかし、INT_MAXに1を加えた場合(2 - 1以上)、記号を反転することがあります。 0111111
と小数点の表現については、11111111
を考えてみてください。 (明らかに32ビットではありませんが、考え方は成り立ちます)
なぜそれが反転するのか混同している場合は、2の補数を参照してください。それは追加を容易にする整数のかなり巧妙な実装です。
編集:INT_MAX + 1
は未定義の動作です。必ずしもINT_MIN
になるとは限りません。しかしx + 1
は必ず> x
ではないので、x == INT_MAX
の場合、答えは明らかに偽です! 32ビットの数値範囲の
'INT_MAX + 1'を評価する動作が定義されていないので、' INT_MAX + 1> INT_MAX'は真と評価できます。 –
@KeithThompsonは必ずしもそうとは限りません。これを反映するように編集されました。ありがとう! – vroomfondel
注である[-2147483648, 2147483647]
[2 、-2 -1]に等しいです。 32ビットのサイズの数に2147483647
に追加するための式x+1 > x
ためので
は[-2147483648, 2147483646]
2147483647
ため
でもないために真であることがx + 1
-2147483648
にしかし、実際に行動にはC標準で 未定義である可能bit overflow多くの実装が発生します。 x = 2147483647
ため
ので、[-2147483648, 2147483646]
でx
のための真の
x + 1 > x
のみx + 1 > x
は、未定義の値は、コンパイラに依存TrueまたはFalseかもしれです。コンパイラが= -2147483648
の値を計算すると、Falseになります。多くの実装で 'iNT_MAX + 1'が' INT_MIN'を生成しますが、実際には動作はC標準で定義されていません。オワーの答えを見てください。 –
@KeithThompsonそれは私にチェックさせることはできませんか? –
ISO Cセクション6.5段落5 –
これに答えるには、 'int型の変数に保持できる有限数の値しかないことを理解する必要があります。 –
' int '値の追加はバイナリまたは10進表記で定義されていません。それは数学的に定義されています。数学的に正しい結果を生み出すために、正しいことをビットに実行するのは実装次第です。 (そして、 'int'は必ずしも32ビットではなく、少なくとも16ビットでなければならず、最近は普通は32ビットですが、それはちょうど何でもよいでしょう) –