简体   繁体   English

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

[英]size_t(-1) and int(-1) under 64-bit system

I wrote a test code for verifying some issues of 64-bit porting. 我编写了一个测试代码来验证64位移植的一些问题。 But I was confused with the following cases: 但是我对以下情况感到困惑:

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);

The output result is: 输出结果为:

size_neg_one = 0xffffffffffffffff
int_neg_one  = 0xffffffff

Obviously, size_neg_one shouldn't equal to int_neg_one . 显然, size_neg_one不应等于int_neg_one But I tried if(size_neg_one == int_neg_one) and got TRUE . 但是我尝试了if(size_neg_one == int_neg_one)并得到TRUE It doesn't match my expectation. 这不符合我的期望。

Could someone explain this condition for me? 有人可以为我解释这种情况吗? Thanks in advance. 提前致谢。

My DEV environment: 64-bit Xubuntu 13.04 with gcc-4.6.3 . 我的DEV环境:具有gcc-4.6.3的 64位Xubuntu 13.04

6.3.1.3 Signed and unsigned integers 6.3.1.3有符号和无符号整数

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged. 1将整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变。
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.60) 2否则,如果新类型是无符号的,则通过重复添加或减去新类型所能表示的最大值之前的值,直到该值在新类型的范围内,来转换该值。60)
3 Otherwise, the new type is signed and the value cannot be represented in it; 3否则,将对新类型进行签名,并且无法在其中表示值; either the result is implementation-defined or an implementation-defined signal is raised. 结果是实现定义的,还是引发实现定义的信号。

So int (32Bit 2-s complement) is converted to size_t (64Bit unsigned), by adding 2^64 to -1. 因此,通过将2 ^ 64加到-1,将int (32Bit 2-s补码)转换为size_t (64Bit unsigned)。

Just about every compiler will warn about such a comparison though. 但是,几乎每个编译器都会警告您进行这种比较。

Most binary operators, including == , work on two values with the same type. 大多数二元运算符(包括== )对相同类型的两个值进行运算。 If the two types are different, then one or both is promoted so that they match. 如果两种类型不同,那么将提升一种或两种,以便它们匹配。

The rules are quite complicated but, in this case, int_neg_one is promoted to size_t . 规则非常复杂,但是在这种情况下, int_neg_one被提升为size_t This uses exactly the same conversion as the cast used to give size_neg_one its value, and so the comparison compares two equal values and yields true . 这与为size_neg_one其值所使用的size_neg_one转换完全相同,因此比较比较两个相等的值并得出true

当您将size_t与INT进行比较时,其中一个会隐式转换为另一个。

Firstly, your printf is broken. 首先,您的printf损坏了。 It produces undefined behavior. 它产生未定义的行为。 You used %x format specifier with an int argument. 您将%x格式说明符与int参数一起使用。 %x requires unsigned int argument, not an int argument. %x需要unsigned int参数,而不是int参数。 While this combination might still be legal for a non-negative int value, it is not defined for negative values. 虽然此组合对于非负int值可能仍然合法,但并未为负值定义该组合。 In other words, the int_neg_one = 0xffffffff output you observe has no particular meaning in the language. 换句话说,您观察到的int_neg_one = 0xffffffff输出在语言中没有特殊含义。 The output is rather obviously meaningless, since the positive value 0xffffffff is out of range of type int on your platform. 输出显然是毫无意义的,因为正值0xffffffff超出平台上int类型的范围。

Secondly, as for size_neg_one == int_neg_one equality, as other have already explained, according to the rules of the language the comparison is performed in the domain of unsigned type size_t , meaning that your comparison is actually interpreted as 其次,对于size_neg_one == int_neg_one相等性,正如其他人已经解释的那样,根据语言规则,比较是在无符号类型size_t的域中执行的,这意味着您的比较实际上被解释为

size_neg_one == size_t(int_neg_one)

The right-hand size produces the same value as your size_t(-1) , which is why the equality holds. 右边的大小会产生与您的size_t(-1)相同的值,这就是相等性成立的原因。

In order to compare values, both operands must have the same type, which is determined by a somewhat complex set of rules; 为了比较值,两个操作数必须具有相同的类型,这由一组较为复杂的规则确定; in particular, in this case, in the unlikely case that size_t is smaller than int , the rules are different than if it is the same size or larger. 特别是在这种情况下,在不太可能的情况下, size_t小于int ,规则与大小相同或更大的规则不同。 Assuming the usual case, however, where size_t is larger than or the same size as int , the int will be converted into size_t . 但是,假设通常情况下,如果size_t大于int或与int相同,则int将被转换为size_t Since size_t is guaranteed to be an unsigned integral type, if the integral type is negative, the results of the conversion are defined as the mathematical correct results of std::numeric_limits<size_t>::max() + 1 + int_value . 由于一定要保证size_t为无符号整数类型,因此,如果整数类型为负,则转换结果将定义为std::numeric_limits<size_t>::max() + 1 + int_value的数学正确结果。 (The mathematically correct results, because within C++, the results of std::numeric_limits<size_t>::max() + 1 are guaranteed to be 0.) (数学上正确的结果,因为在C ++中, std::numeric_limits<size_t>::max() + 1结果保证为0。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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