有意思的警告:c4551 function call missing argument list

缘起

这个端午节又在加班改 bug,没想到改了一个长见识的 bug。因为是过节,而且卷了一天确实有些累,没打算刨根问底。本想简单跟客户沟通一下错误代码是如何引入的。没想到客户对这个问题比较感兴趣,想把砂锅打破。好吧,恭敬不如从命。

在开始之前,先请各位看一段代码,您觉得这段代码能编译通过吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "stdafx.h"

bool AreYouOk()
{
return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
bool bImOk = true;
if (AreYouOk && bImOk)
{
printf("Yeah");
}
return 0;
}

答案是:能编译通过,但是会报警告

惊不惊喜,意不意外?项目里遇到的问题跟上面代码里的问题是一样的。if 语句中的 AreYouOk 本意是想调用这个函数,但是却少写了()。最后的结果是相当于只判断了 bImOk

因为从生成的二进制来看,进行了两个判断:

  1. 判断 AreYouOk 函数的地址是否为空
  2. 判断 bImOk 是否为真。

如下图:

说实话解决完项目中的 bug 后,我的第一反应是:这么写居然能编译通过?难道不是会报错吗?但是事实如此,确实能编译通过,只不过行为和我们预期的有些不一样。

在意识到能确实能编译通过这个事实时,我的第一感觉是应该是项目代码里有与这个函数同名的宏吧?因为在忙碌一天的我的大脑里,我的第一反应是函数就应该与 () 一起使用,完全忘了函数名也可以当成变量使用(比如,可以对函数名取地址赋值给函数指针)。在清醒过来后我想:即使能编译通过,应该会报警告才对。于是在本地快速编写了上面的测试代码,编译。果然有警告—— warning C4551: function call missing argument list

因为项目中的警告信息太多了,已经免疫了,很少关注警告信息。这个问题就被隐藏起来了。

总结

一定要注意查看警告信息!如果可以的话,尽量开启把警告视为错误,即 /WX 选项。这样就会避免类似的问题再次发生了。

您遇到过什么好玩的编译错误吗?私信聊聊吧。

BianChengNan wechat
扫描左侧二维码关注公众号,扫描右侧二维码加我个人微信:)
0%