我想基本上有一个宏缩短器。
宏,FOO(A,B,C)
应扩展为
defined(_FOO_A) || defined(_FOO_B) || defined(_FOO_C)
.
在 GCC 中使用可变参数宏参数而不是实际编写 3 个函数 ( FOO(A)
, FOO(A,B)
, FOO(A,B,C)
) 是否可行?
我想基本上有一个宏缩短器。
宏,FOO(A,B,C)
应扩展为
defined(_FOO_A) || defined(_FOO_B) || defined(_FOO_C)
.
在 GCC 中使用可变参数宏参数而不是实际编写 3 个函数 ( FOO(A)
, FOO(A,B)
, FOO(A,B,C)
) 是否可行?
无法将宏扩展为包含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));
像这样的东西?
#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 标准中。