用__VA_ARGS__在C/C++中进行宏扩展



我发现这两段代码与可变宏有关

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))

相关内容

  • 没有找到相关文章

最新更新