我发现这两段代码与可变宏有关
1.第一个例子用于实现GNU C编译器和Visual C编译器之间的可移植性,但我不明白这个宏是如何一步一步扩展的
MACRO_VA_ARGS(foo, bar, baz)
是先计算内括号还是外括号?
#define MACRO_WITH_3_PARAMS(p1, p2, p3) P1 = p1 | P2 = p2 | P3 = p3
#define PASS_ON(...) __VA_ARGS__
#define MACRO_VA_ARGS(...) PASS_ON(PASS_ON(MACRO_WITH_3_PARAMS)( __VA_ARGS__))
MACRO_VA_ARGS(foo, bar, baz)
第一个例子的所有代码:
#define F_OR(i, a, b, s) for (int i=(a); (s)>0?i<(b):i>(b); i+=(s))
#define F_OR1(e) F_OR(i, 0, e, 1)
#define F_OR2(i, e) F_OR(i, 0, e, 1)
#define F_OR3(i, b, e) F_OR(i, b, e, 1)
#define F_OR4(i, b, e, s) F_OR(i, b, e, s)
#define GET5(a, b, c, d, e, ...) e
#define F_ORC(...) GET5(__VA_ARGS__, F_OR4, F_OR3, F_OR2, F_OR1)
#define FOR(...) F_ORC(__VA_ARGS__)(__VA_ARGS__)
2.我在Github上找到的第二个代码示例,我知道
#define GET5(a, b, c, d, e, ...) e
提取第五个元素,但我不明白这两个宏是如何扩展的:
#define F_ORC(...) GET5(__VA_ARGS__, F_OR4, F_OR3, F_OR2, F_OR1)
#define FOR(...) F_ORC(__VA_ARGS__)(__VA_ARGS__)
第二个例子的所有代码:
#define F_OR(i, a, b, s) for (int i=(a); (s)>0?i<(b):i>(b); i+=(s))
#define F_OR1(e) F_OR(i, 0, e, 1)
#define F_OR2(i, e) F_OR(i, 0, e, 1)
#define F_OR3(i, b, e) F_OR(i, b, e, 1)
#define F_OR4(i, b, e, s) F_OR(i, b, e, s)
#define GET5(a, b, c, d, e, ...) e
#define F_ORC(...) GET5(__VA_ARGS__, F_OR4, F_OR3, F_OR2, F_OR1)
#define FOR(...) F_ORC(__VA_ARGS__)(__VA_ARGS__)
谢谢!
1.第一个非常直接,其中PASS_ON函数仅用于详细说明宏的用法(或混淆(。
最终扩展将是,
MACRO_VA_ARGS(foo, bar, baz) => P1 = foo | P2 = bar | P3 = baz
将逐步扩大
#1
MACRO_VA_ARGS(foo, bar, baz) => PASS_ON(PASS_ON(MACRO_WITH_3_PARAMS)( foo, bar, baz))
#2
PASS_ON(PASS_ON(MACRO_WITH_3_PARAMS)( foo, bar, baz)) => PASS_ON(MACRO_WITH_3_PARAMS( foo, bar, baz))
#3
PASS_ON(MACRO_WITH_3_PARAMS( foo, bar, baz)) => PASS_ON(P1 = foo | P2 = bar | P3 = baz)
#4
PASS_ON(P1 = foo | P2 = bar | P3 = baz) => P1 = foo | P2 = bar | P3 = baz
2.第二个非常有趣,因为它保留了GET5的自变量,GET5提取了第五个元素,在任何情况下都是F_OR1。如果我们调用FOR(5(,
最终扩展将是,
FOR(5) => for (int i=(0); (1)>0?i<(5):i>(5); i+=(1))
将逐步扩大
#1
FOR(5) => F_ORC(5)(5)
#2
F_ORC(5)(5) => GET5(5, F_OR4, F_OR3, F_OR2, F_OR1)(5)
#3
GET5(5, F_OR4, F_OR3, F_OR2, F_OR1)(5) => F_OR1(5)
#4
F_OR1(5) => F_OR(i, 0, 5, 1)
#5
F_OR(i, 0, 5, 1) => for (int i=(0); (1)>0?i<(5):i>(5); i+=(1))