将 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)
我使用了以下几个 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)