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

时间:2014-04-22 06:59:00

标签: c++ 32bit-64bit

我写了一个测试代码,用于验证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环境: 64位Xubuntu 13.04 gcc-4.6.3

5 个答案:

答案 0 :(得分:1)

  

6.3.1.3有符号和无符号整数

     

1当整数类型的值转换为_Bool以外的另一个整数类型时,if   该值可以用新类型表示,不变   2否则,如果新类型是无符号的,则通过重复添加或转换该值   减去一个可以在新类型中表示的最大值   直到该值在新类型的范围内.60)
  3否则,新类型已签名且值无法在其中表示;无论是   结果是实现定义的或引发实现定义的信号。

所以int(32位2-s补码)通过将2 ^ 64加到-1来转换为size_t(64位无符号)。

几乎每个编译器都会警告这样的比较。

答案 1 :(得分:1)

大多数二元运算符(包括==)处理两个具有相同类型的值。如果这两种类型不同,则其中一个或两个都是提升,以便它们匹配。

规则相当复杂,但在这种情况下,int_neg_one会提升为size_t。这使用与用于赋予size_neg_one值的转换完全相同的转换,因此比较会比较两个相等的值并生成true

答案 2 :(得分:0)

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

答案 3 :(得分:0)

首先,您的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)产生相同的值,这就是等式成立的原因。

答案 4 :(得分:0)

为了比较值,两个操作数必须相同 类型,由一些复杂的规则决定;在 特别是在这种情况下,size_t是不可能的 小于int,规则不同于它 相同尺寸或​​更大。然而,假设通常的情况,那里 size_t大于或等于intint 将被转换为size_t。由于size_t得到保证 如果是整数类型,则为无符号整数类型 否定,转换的结果定义为 数学正确的结果 std::numeric_limits<size_t>::max() + 1 + int_value。 (该 数学上正确的结果,因为在C ++中,结果 std::numeric_limits<size_t>::max() + 1的保证是保证的 0.)