缘起
这个端午节又在加班改 bug
,没想到改了一个长见识的 bug
。因为是过节,而且卷了一天确实有些累,没打算刨根问底。本想简单跟客户沟通一下错误代码是如何引入的。没想到客户对这个问题比较感兴趣,想把砂锅打破。好吧,恭敬不如从命。
在开始之前,先请各位看一段代码,您觉得这段代码能编译通过吗?
1 |
|
答案是:能编译通过,但是会报警告。
惊不惊喜,意不意外?项目里遇到的问题跟上面代码里的问题是一样的。if
语句中的 AreYouOk
本意是想调用这个函数,但是却少写了()
。最后的结果是相当于只判断了 bImOk
。
因为从生成的二进制来看,进行了两个判断:
- 判断
AreYouOk
函数的地址是否为空 - 判断
bImOk
是否为真。
如下图:
说实话解决完项目中的 bug
后,我的第一反应是:这么写居然能编译通过?难道不是会报错吗?但是事实如此,确实能编译通过,只不过行为和我们预期的有些不一样。
在意识到能确实能编译通过这个事实时,我的第一感觉是应该是项目代码里有与这个函数同名的宏吧?因为在忙碌一天的我的大脑里,我的第一反应是函数就应该与 ()
一起使用,完全忘了函数名也可以当成变量使用(比如,可以对函数名取地址赋值给函数指针)。在清醒过来后我想:即使能编译通过,应该会报警告才对。于是在本地快速编写了上面的测试代码,编译。果然有警告—— warning C4551: function call missing argument list
。
因为项目中的警告信息太多了,已经免疫了,很少关注警告信息。这个问题就被隐藏起来了。
总结
一定要注意查看警告信息!如果可以的话,尽量开启把警告视为错误
,即 /WX
选项。这样就会避免类似的问题再次发生了。
您遇到过什么好玩的编译错误吗?私信聊聊吧。