十一长假之后第一天上班,继续调试那位还在婚假当中的同事留下的代码。上午查到的一个 Bug 让我相当无语。不过鉴于自己如果思想在开小差的话也很可能会犯类似错误,故记录下来警醒自己。
看看这段代码:
#define ST_ERR -1
……
BYTE result = ST_ERR;
……
if (result == ST_ERR)
return errmsg;
事实上,这个if语句根本就没得到执行。即使 result 在赋值了 ST_ERR 之后从未改变,代码在执行时仍然跳过了判断,继续执行下面的代码。也就是说,result 明明赋值了 ST_ERR,但却不等于 ST_ERR。
难道遇到鬼了,result 中间被篡改了?溢出过?
好吧,其实 result 的确不是 -1,而是 255。看看 BYTE 的定义就清楚了。BYTE 并不是 C/C++ 内建的数据类型。在 Win32 平台上,它通常都被定义为 unsigned char。
到这里就明白了,unsigned 当然不可能有负数。而 ST_ERR 因为用了宏定义,当做常量使用的时候并不会自动转成非负的 unsigned 形式,这样当然不可能相等了。
说穿了,不是负数惹的祸,而是「宏」这个东西惹的祸。如果用 const 常量,因为常量的定义上有类型信息存在,就不会有这个问题了。
当然,这里无意评价宏与 const 常量的好与坏,单纯指出问题而已。目前这个公司的代码,宏用得不少,难保会有菜鸟程序员出这种错,隐患啊!
没有评论:
发表评论