最佳答案
例如:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
根据 C99标准,上述 BAR()
的使用确实是不正确的,因为它将扩大到:
printf("this breaks!",);
注意后面的逗号-不可行。
一些编译器(例如: VisualStudio2010)会悄悄地为您去掉尾部的逗号。其他编译器(例如: GCC)支持将 ##
放在 __VA_ARGS__
前面,如下所示:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
但是有没有一种符合标准的方法来获得这种行为呢? 也许使用多宏?
目前,##
版本似乎得到了相当好的支持(至少在我的平台上是这样) ,但我真的宁愿使用符合标准的解决方案。
先发制人: 我知道我可以只编写一个小函数。我正在尝试使用宏来实现这一点。
编辑 : 这里有一个例子(尽管很简单)说明我为什么要使用 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);
这会自动在我的 BAR ()日志语句中添加一个新行,假设 fmt
始终是双引号 C 字符串。它不会将换行作为单独的 printf ()打印出来,如果日志记录是行缓冲的,并且异步地来自多个源,那么这样做是有好处的。