前段时间在修复某系统的bug时, 发现一位同事在代码中加入了类似如下的语句:
int a = 0;
int b = 0;
/*some codes*/
if ( a + b <= 0) {
/*some codes: invalid a or b*/
}
同事解释说: 用来判断溢出. 听了解释后, 我点头称是, 觉得这是个好招.
刚才, 在看"C Traps and Pitfalls"一书中的"3.6 Integer Overflow"一节时, 顿感羞愧. 在几十年前就已经有很好的解决方案了, 如下:
有符号整数相加溢出的结果是未定义的. 例如有的系统中, 加法操作有权利设置系统的4个标记位: 正, 负, 0, 溢出. 在溢出时, 加法把系统的溢出标记位置1. 然后编译器根据代码来取"负"标记位测试, 将导致测试失败(得不到正确的结果).
而无符号整数是不会溢出的, 所以作者推荐如下的用法:
if ((unsigned int)a + (unsigned int)b > INT_MAX)
complain();
其中INT_MAX的定义在头文件limits.h中
或者使用如下的方法, 不涉及无符号整数的计算:
if (a > INT_MAX - b)
complain();
想看到更好的风景, 不只跟视力有关, 更重要的是: 所站的高度.
References:
C Traps and Pitfalls, ch3.6 Integer Overflow