为什么−1>大小(int)?
考虑下面的代码:
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)
如果 sizeof(int) 是 4。如果是这样,为什么-1 > > size_t(4) 是假的?
这个C++标准符合吗?
Consider the following code:
template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK
Why is -1 > sizeof(int)
true?
- Is it true that
-1
is promoted tounsigned(-1)
and thenunsigned(-1) > sizeof(int)
. - Is it true that
-1 > sizeof(int)
is equivalent to-1 > size_t(4)
if sizeof(int) is 4. If this is so why-1 > size_t(4)
is false?
Is this C++ standard comformant?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这很简单,也很悲伤。在C/C++中:
1U < 2U
(IOW0U
是最小的无符号
值)sizeof
的类型为size_t
size_t
是无符号整数类型-1
-1
-1
-1 1U
被解释为unsigned(-1)
1U
,并且unsigned(-1)
=- 1U
,并且显然- 1U
1U
,所以-1 < 1U 是正确的。
sizeof Something
充当(大部分)作为等效类(!!!)。-1
sizeof Something
结论:这是从 C 继承的设计错误。
规则:
仅使用无符号类型进行模算术、位操作(
&
、|
、^
、<<
、>>
、~
运算符) 、字节操作(unsigned char
在 C/C++ 中表示“字节”)和字符(unsigned char
在 C/C++ 中表示字符)。不要使用无符号类型进行算术运算。
如果函数需要一个永远不应该为负数的整数值,请采用有符号整数,并可以选择在函数中检查该值是否在范围内。
It's simple and sad. In C/C++:
1U < 2U
(IOW0U
is the smallestunsigned
value)sizeof
has typesize_t
size_t
is an unsigned integer type-1 < 1U
is interpreted asunsigned(-1) < 1U
, andunsigned(-1)
=- 1U
, and obviously- 1U < 1U
, so-1 < 1U
is true.sizeof something
acts (mostly) as an equivalent class (!!!).-1 < sizeof something
The conclusion: this is a design error inherited from C.
Rule:
Only use unsigned types for modular arithmetic, bits manipulations (
&
,|
,^
,<<
,>>
,~
operators), byte manipulations (unsigned char
means "byte" in C/C++), and characters (unsigned char
means character in C/C++).Do not use unsigned types to do arithmetic.
If a function expects an integer value that should never be negative, take a signed integer, and optionally check in the function that the value is in range.
以下是标准(ISO 14882)如何解释 abort -1 > sizeof(int)
关系运算符“>”定义于 5.9 (expr.rel/2)
通常的算术转换定义在 5 (expr/9)
... 该模式称为通常的算术转换,其定义如下:
double, ...
积分促销在 4.5 (conv.prom/1) 中定义
sizeof的结果在5.3.3中定义(expr.sizeof/6)
size_t 在 C 标准(ISO 9899)中定义,它是无符号整数类型。
所以对于
-1 > sizeof(int)
,>触发通常的算术转换。通常的算术转换将 -1 转换为 unsigned int,因为 int 无法表示size_t
的所有值。-1
变成一个非常大的数字,具体取决于平台。所以-1 > sizeof(int)
为true
。The following is how standard (ISO 14882) explains abort -1 > sizeof(int)
Relational operator `>' is defined in 5.9 (expr.rel/2)
The usual arithmetic conversions is defined in 5 (expr/9)
... The pattern is called the usual arithmetic conversions, which are defined as following:
double, ...
The integral promotions is defined in 4.5 (conv.prom/1)
The result of sizeof is defined in 5.3.3 (expr.sizeof/6)
size_t is defined in C standard (ISO 9899), which is unsigned integer type.
So for
-1 > sizeof(int)
, the > triggers usual arithmetic conversions. The usual arithmetic conversion converts -1 to unsigned int because int cannot represent all the value ofsize_t
.-1
becomes a very large number depend on platform. So-1 > sizeof(int)
istrue
.因为 unsigned 比有符号更强,并且 -1 从
size_t
开始转换为无符号值,所以实际上-1 == 0xFFFFFFFF > 4
根据 C++ 标准,它应该是这样工作的
Because unsigned is stronger then signed and -1 converted to unsigned value as of
size_t
, so actually-1 == 0xFFFFFFFF > 4
This is how it should work according to C++ standard
因为 -1 被转换为
size_t
并且这是一个无符号数据类型 - 所以(size_t)-1 == 4294967295
(在 32 位系统上)它肯定大于 4例如,如果您将
-Wall
添加到 gcc 设置中,您会收到一条警告,提示您正在比较有符号和无符号数据类型because -1 gets casted to
size_t
and this is an unsigned data type - so(size_t)-1 == 4294967295
(on a 32bit system) which is definitely larger than 4if you add
-Wall
to the gcc settings for example you get a warning that you are comparing a signed and an unsigned data type