我什么时候可以确定如果==运算符对不同类型的积分操作数求值为true,那么操作数是否真的相等?

时间:2015-08-01 17:59:15

标签: c++ integer

我知道积分转换可能非常棘手,并且应用不同整数类型的操作数可能会破坏例如<运算符:

std::cout << (-1 < 1u)
false

甚至是==运营商:

std::cout << (4294967295u == -1)
true

(尽管如此,上述两个例子都会产生警告)

我想知道的是:

  • 如果我将两个操作数与==运算符进行比较,并且任一操作数的值位于另一个操作数的范围内,我是否可以确定如果语句的计算结果为true,则值为真的相等吗?
  • 如果没有,==运营商在什么情况下会产生合理的结果?如何使用它来比较有符号和无符号值而不出错?

2 个答案:

答案 0 :(得分:3)

  
      
  • 如果我将两个操作数与==运算符进行比较,并且任一操作数的值位于另一个操作数的范围内,我是否可以确定如果语句的计算结果为true,则值为真的相等吗?
  •   

即可。只要满足两个条件:

  1. 两个参数都是不可或缺的,
  2. 两种参数类型都具有相同的符号,或者有符号值恰好是非负数。
  3. 但是:这并不意味着这是一个好主意。编译器警告不应掉以轻心。

    对于大多数二元运算符(包括==)和整数操作数,编译器将首先对每个操作数应用整数提升(C ++ 11:§4.5[conv.prom])独立。这会将操作数转换为至少unsigned int或(最好)int。这会保留操作数的所有可能值,但它可以将一种类型从无符号值更改为更大的有符号值。

    接下来,编译器查找公共类型(C ++ 11:§5[expr] / 9)。此类型不会大于两个操作数中的较大者。这里确实可以改变值:可能会发生签名类型转换为无符号类型,在这种情况下,负值不会延续。但由于我们排除了负值,因此这不是问题。

答案 1 :(得分:0)

在无符号和有符号数字之间进行比较时始终处于类似情况 操作将在2个无符号数之间。

在这种情况下

(-1 < 1u) 
-1 = 0b11111111111111111111111  (1* 32 times)=4294967295u 
1u = 0b00000000000000000000001

所以很清楚这是错误的,因为

4294967295u = 0b11111111111111111111111

你不能代表4294967295不在unsigned int。

你可以看到

-1==4294967295u

一般来说,在这种情况下,一些编译器会给你警告,但你必须小心..