今天同事遇到了个奇怪的问题,我帮忙看了一下,发现了比较神奇的事情,记录一下。
模拟一下代码基本上是这样:
int a = 10 ;
unsigned int b = 2 ;
if (b - a < 0)
{
// do something
}
然后我发现 b - a < 0这个判断返回的是false,也就是这个if语句不成立。
google了一下在stackoverflow里找到了答案,这是C的标准,当 int 和 unsigned int 操作时,int会被强制转换成unsigned int ,也就是说 b - a的结果也是一个unsigned int,它的值总是>= 0的,在XCode 5.1上这段代码直接就给出警告了("Comparison of unsigned expression < 0 is always false")
下面是stackoverflow的链接:
http://stackoverflow.com/questions/6770258/how-do-promotion-rules-work-when-the-signedness-on-either-side-of-a-binary-opera
引用accepted answer中的一段,讲述在C中二元操作符是如何处理两个不同类型变量的。
Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:
- If either operand is of type
long double
, the other shall be converted tolong double
. - Otherwise, if either operand is
double
, the other shall be converted todouble
. - Otherwise, if either operand is
float
, the other shall be converted tofloat
. - Otherwise, the integral promotions shall be performed on both operands.
- Then, if either operand is
unsigned long
the other shall be converted tounsigned long
. - Otherwise, if one operand is a
long int
and the otherunsigned int
, then if along int
can represent all the values of anunsigned int
, theunsigned int
shall be converted to along int
; otherwise both operands shall be converted tounsigned long int
. - Otherwise, if either operand is
long
, the other shall be converted tolong
. - Otherwise, if either operand is
unsigned
, the other shall be converted tounsigned
.
[Note: otherwise, the only remaining case is that both operands are int
]
后记:其实这些内容在深入理解计算机系统这本书里早有介绍,只能说自己的基础还是不够,惭愧了,总之还要多读书啊。