零参数宏

Macro with zero arguments

我不知道这段代码有什么问题。当我将 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() 被正确扩展:

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)

When I run g++ -E on this file, LOG_INFO() IS expanded correctly:

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=56825 or https://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% 确定这对你的情况有用。