2011-10-08

都是负数惹的祸?

十一长假之后第一天上班,继续调试那位还在婚假当中的同事留下的代码。上午查到的一个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常量的好与坏,单纯指出问题而已。目前这个公司的代码,宏用得不少,难保会有菜鸟程序员出这种错,隐患啊!

没有评论:

发表评论