一个类型提升的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)

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