请考虑以下代码:
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
提升为unsigned(-1)
然后unsigned(-1) > sizeof(int)
是否属实。-1 > sizeof(int)
是否等同于-1 > size_t(4)
。如果是这样,为什么-1 > size_t(4)
为假?此C ++标准是否符合要求?
答案 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)
中定义...该模式称为通常的算术转换,定义如下:
整体促销活动在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 ++中:
1U < 2U
(IOW 0U
是最小的unsigned
值)sizeof
的类型为size_t
size_t
是无符号整数类型-1 < 1U
被解释为unsigned(-1) < 1U
,而unsigned(-1)
= - 1U
,显然是- 1U < 1U
,所以-1 < 1U
是的。sizeof something
(大部分)作为同等级别(!!!)。-1 < sizeof something
结论:这是从C继承的设计错误。
<强>规则:强>
仅使用无符号类型进行模运算,位操作(&
,|
,^
,<<
,>>
,~
运算符),字节操作(unsigned char
表示&#34;字节&#34;在C / C ++中),字符(unsigned char
表示C / C ++中的字符)。
请勿使用无符号类型进行算术运算。
如果某个函数需要一个永远不应该为负数的整数值,请取一个有符号整数,并可选择检查该值在范围内的函数。