将 0 附加到不完整的宏参数列表

Appending 0s to an incomplete macro parameter list

我使用了以下几个 C 预处理器宏:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__, 0, 0, 0, 0)

当使用 1、2 或 3 个参数调用 FILL_PARAMS 时,后面的(未指定)按预期变为 0,但如果不提供参数,则会出错。

有没有办法添加对无参数的支持?

澄清:
目前支持以下用途:

FILL_PARAMS(1)         // => 1, 0, 0, 0
FILL_PARAMS(1, 2)      // => 1, 2, 0, 0
FILL_PARAMS(1, 2, 3)   // => 1, 2, 3, 0

我想添加对以下极端情况的支持:

FILL_PARAMS()          // => 0, 0, 0, 0

欢迎提供帮助。

找到了一个 hack-ish 解决方案:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4
#define FILL_PARAMS(...) TAKE4( __VA_ARGS__ + 0, 0, 0, 0, 0)

这至少适用于以下测试用例。

int i = 120;
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS());
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(i));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3, 4));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3, i));

您可以通过多种方式实现这一点,最简单的方法是使用

FILL_PARAMS(0)

作为空壳。

另一种更复杂、使用起来更麻烦的方法是始终在最后一个参数后面加上逗号:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__ 0, 0, 0, 0)

/* called like: */
FILL_PARAMS()
FILL_PARAMS(1,)
FILL_PARAMS(1,2,)
FILL_PARAMS(1,2,3,)

或者通过使用 GCC 的逗号吞咽扩展来发挥一点创意:

#define TAKE4(a1, a2, a3, a4, a5, ...) a2, a3, a4, a5
#define FILL_PARAMS(...) TAKE4(0, ##__VA_ARGS__, 0, 0, 0, 0)