C99中可变参数宏的空参数存在一个众所周知的 问题。例:#define FOO(...) printf(__VA_ARGS__)#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)FOO("this works fine");BAR("this breaks!");BAR()根据C99标准,上面的使用确实是不正确的,因为它将扩展为:printf("this breaks!",);请注意结尾的逗号-不可行。一些编译器(例如:Visual Studio 2010)将悄悄地为您消除尾随的逗号。其他编译器(例如: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);假定fmt始终是双引号的C字符串,这会自动向我的BAR()记录语句添加换行符。它不会将换行符作为单独的printf()打印,如果日志记录是行缓冲的并且异步地来自多个源,则这是有利的。
3 回答

繁星coding
TA贡献1797条经验 获得超4个赞
这不是一个通用的解决方案,但是对于printf,您可以添加一个换行符,例如:
#define BAR_HELPER(fmt, ...) printf(fmt "\n%s", __VA_ARGS__)
#define BAR(...) BAR_HELPER(__VA_ARGS__, "")
我相信它会忽略格式字符串中未引用的任何其他参数。因此,您甚至可以摆脱:
#define BAR_HELPER(fmt, ...) printf(fmt "\n", __VA_ARGS__)
#define BAR(...) BAR_HELPER(__VA_ARGS__, 0)
我不敢相信没有标准方法即可批准C99。AFAICT该问题也存在于C ++ 11中。
- 3 回答
- 0 关注
- 2152 浏览
添加回答
举报
0/150
提交
取消