零参数的宏

时间:2015-06-28 00:24:03

标签: c++ macros

我无法弄清楚这段代码有什么问题。当我将1个参数传递给LOG_INFO时,它工作正常,但失败并带有0个参数。

#define LOG_INFO(...) CLOG(INFO, "default", ##__VA_ARGS__)

LOG_INFO() << "Log using default file";

编译此代码时出现此错误:

error:
expected primary-expression before ‘)’ token

这就是我调试它所做的。

当我在此文件上运行g++ -E时,LOG_INFO() IS已正确扩展:

CLOG(INFO, "default") << "Log using default file";

当我替换

LOG_INFO() << "Log using default file";

CLOG(INFO, "default") << "Log using default file";

编译好!但是当我放回预扩展宏时,它再次失败。

回答评论员: 这是CLOG

的定义
#define CLOG(LEVEL, ...)\
    C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)

完整档案可以在这里找到:

https://github.com/easylogging/easyloggingpp/blob/master/src/easylogging%2B%2B.h

运行: gcc版本4.7.2(Debian 4.7.2-5)

1 个答案:

答案 0 :(得分:1)

  

当我在此文件上运行g++ -E时,LOG_INFO() IS已正确扩展:

     

CLOG(INFO, "default") << "Log using default file";

我不认为这是正确扩展的。它应该完全扩展。

CLOG(INFO, "default")

不应该在扩展文件中。它应该扩展到

CINFO(el::base::Writer, el::base::DispatchAction::NormalLog, "default")

反过来应该扩展到其他东西。实际的行将是一些不包含宏的疯狂C ++。

我认为您遇到了##__VA_ARGS__引擎中的缺陷。与https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56825https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61613类似的内容。

您可以通过替换

进行测试
#define LOG_INFO(...) CLOG(INFO, "default", ##__VA_ARGS__)

#define LOG_INFO() CLOG(INFO, "default")

并查看g++ -E的输出。

关于可能的解决方案,你可能会有一些双重扩展技巧。

#define LOG_INFO_HELPER(...) , ## __VA_ARGS__
#define LOG_INFO_COMMA_AND(...) LOG_INFO_HELPER(__VA_ARGS__)
#define LOG_INFO(...) CLOG(INFO, "default" LOG_INFO_COMMA_AND(__VA_ARGS__))

请参阅https://llvm.org/bugs/show_bug.cgi?id=19141

我不是100%确定这会对你的情况有效。