为什么是-1>的sizeof(int)的?

时间:2010-06-23 09:16:40

标签: c++ type-conversion sizeof unsigned modular

请考虑以下代码:

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. -1提升为unsigned(-1)然后unsigned(-1) > sizeof(int)是否属实。
  2. 如果sizeof(int)为4,那么-1 > sizeof(int)是否等同于-1 > size_t(4)。如果是这样,为什么-1 > size_t(4)为假?
  3. 此C ++标准是否符合要求?

4 个答案:

答案 0 :(得分:14)

因为unsigned强度更高然后签名并且-1从size_t转换为无符号值,所以实际上-1 == 0xFFFFFFFF > 4

根据C ++标准,它应该如何工作

答案 1 :(得分:14)

以下是标准(ISO 14882)如何解释abort -1&gt;的sizeof(int)的

关系运算符`&gt;'在5.9(expr.rel / 2)中定义

  

通常的算术转换是   在算术或算术的操作数上执行   枚举类型。 ...

通常的算术转换在5(expr / 9)

中定义

...该模式称为通常的算术转换,定义如下:

  • 如果任一操作数的类型为long 双,......
  • 否则,如果任一操作数是dobule,...
  • 否则,如果任一操作数是浮点数,......
  • 否则,应对两个操作数执行整体促销。
  • ...

整体促销活动在4.5(conv.prom / 1)

中定义
  

char类型的rvalue,signed char,   unsigned char,short int或unsigned   short int可以转换为   如果int可以,则为int类型的rvalue   表示源的所有值   类型;否则,源rvalue可以   转换为类型的右值   unsigned int。

sizeof的结果在5.3.3(expr.sizeof / 6)中定义

  

结果是类型的常量   为size_t

size_t在C标准(ISO 9899)中定义,无符号整数类型

因此对于-1 > sizeof(int),&gt;触发通常的算术转换。通常的算术转换将-1转换为unsigned int,因为int不能表示size_t的所有值。 -1变得非常大,取决于平台。因此-1 > sizeof(int)true

答案 2 :(得分:4)

因为-1被转换为size_t并且这是一个无符号数据类型 - 所以(size_t)-1 == 4294967295(在32位系统上)绝对大于4

如果您将-Wall添加到gcc设置中,例如,您会收到一条警告,指出您正在比较已签名和未签名的数据类型

答案 3 :(得分:2)

简单而悲伤。在C / C ++中:

  1. 大部分时间,无符号整数类型具有模块整数的语义(它们代表等价类)
  2. 无符号整数类型的比较具有通常整数排序的语义,因此1U < 2U(IOW 0U是最小的unsigned值)
  3. sizeof的类型为size_t
  4. size_t是无符号整数类型
  5. Point(1)意味着涉及有符号和无符号整数的混合算术计算是在无符号的模运算中完成的:这是唯一可能不违反&#34;无符号均值模块&#34;规则。将整数转换为等价于它的等价类的等价类是微不足道的。 (而另一种方式则需要选择一个整数来表示等价类。)
  6. 第(5)点意味着-1 < 1U被解释为unsigned(-1) < 1U,而unsigned(-1) = - 1U,显然是- 1U < 1U,所以-1 < 1U是的。
  7. 积分(1,3,4)暗示sizeof something(大部分)作为同等级别(!!!)。
  8. 这一切都意味着-1 < sizeof something
  9. 结论:这是从C继承的设计错误。

    <强>规则:

    仅使用无符号类型进行模运算,位操作(&|^<<>>~运算符),字节操作(unsigned char表示&#34;字节&#34;在C / C ++中),字符(unsigned char表示C / C ++中的字符)。

    请勿使用无符号类型进行算术运算。

    如果某个函数需要一个永远不应该为负数的整数值,请取一个有符号整数,并可选择检查该值在范围内的函数。