20

次のコードを検討してください。

template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK

なぜ-1 > sizeof(int)本当ですか?

  1. に昇格-1unsigned(-1)、その後unsigned(-1) > sizeof(int).
  2. sizeof(int) が 4 の場合-1 > sizeof(int)と同等であることは trueですか。そうである場合、 false はなぜですか?-1 > size_t(4)-1 > size_t(4)

これは C++ 標準に準拠していますか?

4

4 に答える 4

15

以下は、標準(ISO 14882)がabort -1> sizeof(int)を説明する方法です。

関係演算子`>'は5.9(expr.rel/2)で定義されています

通常の算術変換は、算術型または列挙型のオペランドで実行されます。..。

通常の算術変換は5(expr / 9)で定義されています

...このパターンは通常の算術変換と呼ばれ、次のように定義されます。

  • いずれかのオペランドがlongdouble型の場合、..。
  • それ以外の場合、いずれかのオペランドがdobuleの場合、..。
  • それ以外の場合、いずれかのオペランドがfloatの場合、..。
  • それ以外の場合、積分昇格は両方のオペランドで実行されます。
  • ..。

統合プロモーションは4.5(conv.prom / 1)で定義されています

intがソース型のすべての値を表すことができる場合、char型、signed char、unsigned char、short int、またはunsignedshortintの右辺値をint型の右辺値に変換できます。それ以外の場合は、ソース右辺値をunsignedint型の右辺値に変換できます。

sizeofの結果は、5.3.3(expr.sizeof / 6)で定義されています。

結果は、タイプsize_tの定数です。

size_tは、符号なし整数型であるC標準(ISO 9899)で定義されています。

したがって、-1 > sizeof(int)の場合、>は通常の算術変換をトリガーします。intは。のすべての値を表すことができないため、通常の算術変換では-1がunsignedintに変換されますsize_t-1プラットフォームに応じて非常に多くなります。です。-1 > sizeof(int)_true

于 2010-06-23T10:50:24.507 に答える
14

unsignedはsignedよりも強力であり、-1は、の時点でunsigned値に変換されるsize_tため、実際には-1 == 0xFFFFFFFF > 4

これは、C++標準に従ってどのように機能するかです。

于 2010-06-23T09:19:26.247 に答える
4

-1がキャストされsize_t、これは符号なしデータ型(size_t)-1 == 4294967295であるため(32ビットシステムの場合)、これは間違いなく4より大きくなります。

-Wallたとえば、gcc設定に追加すると、符号付きデータ型と符号なしデータ型を比較しているという警告が表示されます。

于 2010-06-23T09:51:31.957 に答える
2

シンプルで悲しいです。C/C++ の場合:

  1. ほとんどの場合、符号なし整数型はモジュラー整数のセマンティックを持ちます (それらは等価クラスを表します)。
  2. 符号なし整数型の比較には、通常の整数の順序付けのセマンティクスがあるため、1U < 2U(IOW0Uが最小unsigned値)
  3. sizeofタイプありsize_t
  4. size_t符号なし整数型です
  5. ポイント (1) は、符号付き整数と符号なし整数を含む混合算術計算が符号なし剰余算術で行われることを意味します。これは、「符号なし平均剰余」規則に違反しない唯一の可能性です。整数を、それに相当する整数の等価クラスに変換するのは簡単です。(逆の場合は、等価クラスを表す整数を選択する必要があります。)
  6. ポイント (5)は、および=-1 < 1Uとして解釈されることを意味し、明らかに、そうです。unsigned(-1) < 1Uunsigned(-1)- 1U- 1U < 1U-1 < 1U
  7. ポイント (1,3,4) は、sizeof something(ほとんど) 同等のクラス (!!!) として機能することを意味します。
  8. これはすべて、-1 < sizeof something

結論: これは C から継承された設計エラーです。

ルール:

&モジュラ演算、ビット操作 ( 、|^<<>>~演算子)、バイト操作 ( unsigned charC/C++ で「バイト」を意味する)、および文字 ( C/C++ で文字を意味する) には、符号なし型のみを使用してunsigned charください。

演算を行うために符号なしの型を使用しないでください。

関数が負であってはならない整数値を想定している場合は、符号付き整数を取り、必要に応じて値が範囲内にあることを関数にチェックインします。

于 2011-12-09T04:57:50.180 に答える