![](/img/trans.png)
[英]uint32_t as vector index has better performance than size_t in 64-bit
[英]size_t(-1) and int(-1) under 64-bit system
我编写了一个测试代码来验证64位移植的一些问题。 但是我对以下情况感到困惑:
size_t size_neg_one = (size_t(-1));
int int_neg_one = -1;
printf("size_neg_one = %#zu, int_neg_one = %#x\n", size_neg_one, int_neg_one);
输出结果为:
size_neg_one = 0xffffffffffffffff
int_neg_one = 0xffffffff
显然, size_neg_one
不应等于int_neg_one
。 但是我尝试了if(size_neg_one == int_neg_one)
并得到TRUE
。 这不符合我的期望。
有人可以为我解释这种情况吗? 提前致谢。
我的DEV环境:具有gcc-4.6.3的 64位Xubuntu 13.04 。
6.3.1.3有符号和无符号整数
1将整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变。
2否则,如果新类型是无符号的,则通过重复添加或减去新类型所能表示的最大值之前的值,直到该值在新类型的范围内,来转换该值。60)
3否则,将对新类型进行签名,并且无法在其中表示值; 结果是实现定义的,还是引发实现定义的信号。
因此,通过将2 ^ 64加到-1,将int
(32Bit 2-s补码)转换为size_t
(64Bit unsigned)。
但是,几乎每个编译器都会警告您进行这种比较。
大多数二元运算符(包括==
)对相同类型的两个值进行运算。 如果两种类型不同,那么将提升一种或两种,以便它们匹配。
规则非常复杂,但是在这种情况下, int_neg_one
被提升为size_t
。 这与为size_neg_one
其值所使用的size_neg_one
转换完全相同,因此比较比较两个相等的值并得出true
。
当您将size_t与INT进行比较时,其中一个会隐式转换为另一个。
首先,您的printf
损坏了。 它产生未定义的行为。 您将%x
格式说明符与int
参数一起使用。 %x
需要unsigned int
参数,而不是int
参数。 虽然此组合对于非负int
值可能仍然合法,但并未为负值定义该组合。 换句话说,您观察到的int_neg_one = 0xffffffff
输出在语言中没有特殊含义。 输出显然是毫无意义的,因为正值0xffffffff
超出平台上int
类型的范围。
其次,对于size_neg_one == int_neg_one
相等性,正如其他人已经解释的那样,根据语言规则,比较是在无符号类型size_t
的域中执行的,这意味着您的比较实际上被解释为
size_neg_one == size_t(int_neg_one)
右边的大小会产生与您的size_t(-1)
相同的值,这就是相等性成立的原因。
为了比较值,两个操作数必须具有相同的类型,这由一组较为复杂的规则确定; 特别是在这种情况下,在不太可能的情况下, size_t
小于int
,规则与大小相同或更大的规则不同。 但是,假设通常情况下,如果size_t
大于int
或与int
相同,则int
将被转换为size_t
。 由于一定要保证size_t
为无符号整数类型,因此,如果整数类型为负,则转换结果将定义为std::numeric_limits<size_t>::max() + 1 + int_value
的数学正确结果。 (数学上正确的结果,因为在C ++中, std::numeric_limits<size_t>::max() + 1
结果保证为0。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.