例:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
Run Code Online (Sandbox Code Playgroud)
BAR()根据C99标准,上述用途确实不正确,因为它将扩展到:
printf("this breaks!",);
Run Code Online (Sandbox Code Playgroud)
请注意尾随逗号 - 不可行.
一些编译器(例如:Visual Studio 2010)将悄然摆脱那个尾随的逗号.其他编译器(例如:GCC)支持放在##前面__VA_ARGS__,如下所示:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
但有没有符合标准的方法来获得这种行为?也许使用多个宏?
现在,该##版本似乎得到了相当好的支持(至少在我的平台上),但我真的更喜欢使用符合标准的解决方案.
先发制人:我知道我可以写一个小功能.我正在尝试使用宏来做到这一点.
编辑:以下是我想要使用BAR()的一个例子(虽然简单):
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
Run Code Online (Sandbox Code Playgroud)
这会自动为我的BAR()日志记录语句添加换行符,假设fmt它始终是双引号C字符串.它不会将换行符打印为单独的printf(),如果日志记录是行缓冲的并且异步来自多个源,则这是有利的.