这个宏
#define f(x) x x
f (1
#undef f
#define f 2
f)
根据this link扩展到此1 2 1 2
。
它实际上是这样做的,我已经使用Xcode Product > Perform Action > Preprocess
进行了验证,但是在扩展此宏时预处理器遵循了哪些步骤?
答案 0 :(得分:3)
初步情况:
f (1
#undef f
#define f 2
f)
如果我们参考您提供的链接,宏将按两个步骤进行预处理:
第1步:争论预扩展
如果在宏调用中,重新定义了该宏,那么新的 定义在参数预扩展时及时生效
将用作类函数宏的参数的f
替换为2:
f(1 f) -> f (1 2)
第2步:更正参数
但原始定义仍用于参数替换
使用其原始定义解析类似函数的宏f
:
f(1 2) -> 1 2 1 2
整件事实际上等同于以下内容:
#define f(x) x x
#define g 2
f(1 g)
答案 1 :(得分:0)
我认为发生的事情如下,为了能够更好地可视化步骤,让我们通过添加可区分的括号来重写#define
语句。
#define f(x) (x) [x]
f (1
#undef f
#define f 2
f)
//注意,这不会产生有效的C代码。我正在玩它以了解预处理所采取的操作,而不是编译它。通过Product>查看预处理器的结果行动>正如我上面所示的预处理。
因此,预处理器采取的第一步是替换,x被语句中提供的值替换(本例中为“1”),宏值中有2倍x,因此相同的替换发生两次。这里的()和[]括号有助于区分两条路径:
(1
#undef f
#define f 2
f) [1
#undef f
#define f 2
f]
然后#undef
宏f
, 存在,并将其重新定义为f 2
(1 f) [1 f]
在最后一步,简单地用f
替换它当前携带的值,在这种情况下2
(1 2) [1 2]
就是这样。预期结果1 2 1 2
已被替换为基础。