一个类型提升的bug

今天碰到一个由于类型提升的bug, 即使找到bug后, 仍花了好大功夫才找到解释, 感觉此坑比较隐蔽, 在此小记一下.

有类似下面一段代码:

unsigned char a;
unsigned char b;

a = -1;
b = 0;
if (a == b - 1)
printf("equal");
else
printf("not equal");

理论上当a为-1, b为0时应该打印出equal. 可事实恰恰相反, 打印出来的是not equal.

C语言中有以下类型提升规则:
2. 一般常数为int型
1. 二元操作符如果两个操作数具有不同的类型, 那么将较低的类型提升为较高的类型, 运算的结果为较高的类型
2. 将char与short类型的操作数转换为int类型

a,b被提升为int.
因为a是无符号型char, 因此a不会被进行符号扩展, 因此会被提升为0x000000ff
因为b是无符号型char, 因此a不会被进行符号扩展, 因此会被提升为0x00000000

if (a == b - 1)
//等价于
if (0x000000ff == 0xffffffff)

因此在有可能出现类型的地方一定要格外小心.

发布者

重归混沌

一个很固执的人。 他固执的一定要把‘{’在右边。 他固执的不使用任何IDE,而只使用vim + Makefile。

3 thoughts on “一个类型提升的bug”

    1. @gzfgeh char基实本质上是不能用来用做数值传输的, 不便于移植, 因为char是分为sign char与unsigned char, 至于char到底是哪一种取决于编译器的实现。 如果使用gcc则可以使用参数来指定。 如题, 如果是signed char则在类型提升时是会进行符号扩展的,其他同理。

发表评论

电子邮件地址不会被公开。 必填项已用*标注