## __ VA_ARGS__在C99下零args时不吞咽逗号

时间:2016-05-13 09:22:14

标签: c macros c-preprocessor variadic-macros

我想使用如下的宏:

#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的##下获得所需的逗号吞咽行为?

3 个答案:

答案 0 :(得分:1)

是的,##__VA_ARGS__是GNU扩展。

答案 1 :(得分:1)

这是预期的行为。吞没逗号没有标准方法。

幸运的是,gccclangxlc支持##__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)上均可正常运行。