繁体   English   中英

64位系统下的size_t(-1)和int(-1)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM