我有这些行
#define LOG(fp, fmt, ...) fprintf(fp, "%s:%d: "fmt, __FILE__, __LINE__, ## __VA_ARGS__)
#define OUT(fmt, ...) LOG(stdout, fmt, __VA_ARGS__)
编译器显示OUT错误。如何从OUT中调用LOG?
错误讯息:
OUT("Hello world");
时,答案 0 :(得分:3)
简短的解释是因为我从评论中得到了这些代码:##
##__VA_ARGS__
是预处理器的非标准扩展(最初来自gcc,现在也得到了clang的支持)。它的作用是如果在没有可变参数的情况下调用可变参数宏,则删除多余的前一个逗号。也就是说,
#define FOO(bar, ...) foo(bar, __VA_ARGS__)
无法使用一个参数调用,因为它会扩展为foo(argument,)
,
#define FOO(bar, ...) foo(bar, ##__VA_ARGS__)
可以,因为逗号被静默删除,扩展名为foo(argument)
。
因此,您的问题的解决方案是使用
// vv--- these are important here
#define OUT(fmt, ...) LOG(stdout, fmt, ##__VA_ARGS__)
否则,在只有一个参数的OUT
扩展中,__VA_ARGS__
中的LOG
不会为空,因为它是从
LOG(stdout, "Hello, world.",)
而不是
LOG(stdout, "Hello, world.")
...而##
中__VA_ARGS__
之前的LOG
将无效。您收到编译器消息,因为LOG
的扩展中有一个额外的逗号(fprintf
调用以,)
结尾)。
答案 1 :(得分:0)
...
中的OUT(fmt, ..)
意味着需要传递至少一个参数,然后只传递fmt
。例如:
OUT("%s", "Hello World");
如果这样做##
没用,宏看起来应该是这样的:
#define LOG(fp, fmt, ...) fprintf((fp), "%s:%d: "fmt, __FILE__, __LINE__, __VA_ARGS__)
#define OUT(fmt, ...) LOG(stdout, fmt, __VA_ARGS__)