如何在宏中扩展可变参数?

时间:2012-12-21 22:28:46

标签: c gcc c-preprocessor c99 variadic-macros

我想基本上有一个宏缩短器。

FOO(A,B,C)应扩展为 defined(_FOO_A) || defined(_FOO_B) || defined(_FOO_C)

GCC中是否可以使用可变参数宏参数而不是实际编写3个函数(FOO(A)FOO(A,B)FOO(A,B,C))?

2 个答案:

答案 0 :(得分:3)

无法将宏扩展为包含defined关键字的内容:

  

如果由于此替换而生成令牌defined   defined一元运算符的处理或使用与其中一个不匹配   在宏替换之前的两个指定表单,行为是   未定义。

所以你不能用defined做到这一点。如果您愿意通过仅测试FOO_A_FOO_B_的值来放宽该约束,那么可以使用P99来实现此目的。例如,只是做一个逻辑或一个变量列表

#if P99_ORS(A, B, C)
...
#endif

P99_ORS表达式扩展为

((((A) || (B))) || (C))

然后评估#if表达式。

如果你想做一些宏编程,还有办法将它首先扩展到你喜欢的令牌列表中

#define P00_NAME_X(NAME, X, I) P99_PASTE2(NAME, X)
#define CONDITION(NAME, ...) P99_ORS(P99_FOR(FOO_, P99_NARG(__VA_ARGS__), P00_SEQ, P00_NAME_X, __VA_ARGS__))

这样

CONDITION(A, B, C, toto);

将扩展为

((((((FOO_A) || (FOO_B))) || (FOO_C))) || (FOO_toto));

答案 1 :(得分:2)

这样的东西?

#include <stdio.h>

#define FOO(A, B, C) (FOO_X(A) || FOO_X(B) || FOO_X(C))
#define FOO_X(x) defined(_FOO_##x)

// just to print it
#define QUOTE(...) QUOTE_AUX(__VA_ARGS__)
#define QUOTE_AUX(...) #__VA_ARGS__

int main(void)
{
    puts(QUOTE(FOO(a, b, c)));
}

编辑:实际上,这会在所有C标准中产生未定义的行为