2013-07-05 8 views
8

私はちょうど学校でCを学び始めています、私は基本的な概念を保持しようとしています。これは常にtrueですか?

私たちの宿題は、すべてのint x: x+1 > x

ため

がfalseの場合、真と反例場合推論を与え、真か偽かどうかを判断し、疑問を持っています。

int型が32ビットであり、基本的に整数がバイナリ形式であることを教えてくれたので、私は混乱しています。 x + 1は1の小数点に1を加えますか?

+10

これに答えるには、 'int型の変数に保持できる有限数の値しかないことを理解する必要があります。 –

+1

' int '値の追加はバイナリまたは10進表記で定義されていません。それは数学的に定義されています。数学的に正しい結果を生み出すために、正しいことをビットに実行するのは実装次第です。 (そして、 'int'は必ずしも32ビットではなく、少なくとも16ビットでなければならず、最近は普通は32ビットですが、それはちょうど何でもよいでしょう) –

答えて

24
x + 1 > x 

INT_MAX + 1がオーバーフローであり、したがってx + 1 > x発現はINT_MAXx値は未定義の動作値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の式)、攻撃者はサーバープログラムで権限昇格を得ることができました(私が正しく覚えておけば悪用可能なバッファオーバーフローの可能性を開くことによって)。

+3

INT_MAX + 1はINT_MINであることが保証されていますか? – vroomfondel

+5

@rogaos 'INT_MAX + 1'は未定義の動作を呼び出します。通常は* INT_MINになりますが、これはどのような仕様でも保証されません。 – cdhowie

+2

@rogaosええ、何?オーバーフローした場合、UBを呼び出します。それは何かであることは保証されていませんが、実際にはおそらく 'INT_MIN'になります。 –

3

私はあなたに答えを渡したくないので、正しい軌道に乗るべき質問を返信します。

xが32ビット符号付き整数に格納できる最大値の場合、x + 1とは何ですか? (2,147,483,647)

+7

しかしこれは答えではありません。コメントでなければなりません。 –

+0

これはオーバーフローの原因になりますか? ...またはそれは負の値に回り込むでしょうか? – gormandy

+3

@DavidHeffernanおそらく、ここで重要なのは思考プロセスであり、答えではないので、私は宿題関連の質問に答えるために別のアプローチを取っています。しかし、それがあなたをより幸せにするなら、私は明白な答えを加えます。 – cdhowie

0

x(あなたの頭の中で)に値を与えてください。今、2としましょう:

```(2 + 1) > 2``` 

本当ですか、偽ですか?そして、xの他の値については?

整数が32ビットで格納されている場合、xに1を加算すると(x + 1 < x)になることはありますか?

-1

はい、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ビットの数値範囲の

+0

'INT_MAX + 1'を評価する動作が定義されていないので、' INT_MAX + 1> INT_MAX'は真と評価できます。 –

+0

@KeithThompsonは必ずしもそうとは限りません。これを反映するように編集されました。ありがとう! – vroomfondel

4

注である[-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になります。
+3

多くの実装で 'iNT_MAX + 1'が' INT_MIN'を生成しますが、実際には動作はC標準で定義されていません。オワーの答えを見てください。 –

+0

@KeithThompsonそれは私にチェックさせることはできませんか? –

+2

ISO Cセクション6.5段落5 –

関連する問題