我想使用如下的宏:
#define x(...) y(a,##__VA_ARGS__,b)
像这样展开:
x(); -> y(a,b);
x(1); -> y(a,1,b);
使用-std=gnu99
,效果非常好。
然而,使用-std=c99
,它看起来像这样:
x(); -> y(a,,b);
x(1); -> y(a,1,b);
##
没有任何区别 - 它不会吞下逗号。
在C99下的其他用法中,例如#define x(a,...) y(a,##__VA_ARGS__)
,逗号吞咽效果很好。
我可以做什么,如果有的话,使用GNU扩展-std=c99
或其他方法在clang的##
下获得所需的逗号吞咽行为?
答案 0 :(得分:1)
是的,##__VA_ARGS__
是GNU扩展。
答案 1 :(得分:1)
这是预期的行为。吞没逗号没有标准方法。
幸运的是,gcc
,clang
和xlc
支持##__VA_ARGS__
gnu扩展名,而msvc
会自动吞下逗号。
如果您不想依赖上述语言扩展,那么获取可变参数宏的惯用ISO C90方式就是这样:
#define x(args) y args
/* notice the extra parantheses */
x((a, b, c, d));
如果您不想使用这些解决方案中的任何一种,您可以随时使用参数计数,如已回答here。
答案 2 :(得分:0)
正如您所描述的,以下模式可以正常工作。
#define x(a,...) y(a,##__VA_ARGS__)
运行以下代码段后,我猜##__VA_ARGS__
会在存在前缀args(例如e_x中的_)时始终吞下逗号。
#define x(...) y(a,c, ##__VA_ARGS__, b)
#define e_x(_, ...) y(a, c, ##__VA_ARGS__, b)
x();
x(a);
x(a, b);
e_x();
e_x(a);
e_x(a, b);
您可以获得结果:
y(a,c,, b);
y(a,c,a, b);
y(a,c,a, b, b);
y(a, c, b);
y(a, c, b);
y(a, c, b, b);
以上示例在我的计算机(macos和linux)上均可正常运行。