零参数宏
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% 确定这对你的情况有用。
我不知道这段代码有什么问题。当我将 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% 确定这对你的情况有用。