C语言中的宏展开

4
这个宏
#define f(x) x x
     f (1
     #undef f
     #define f 2
     f)

根据此链接,它会扩展为1 2 1 2

实际上,当我使用Xcode Product > Perform Action > Preprocess进行验证时,它确实这样做了。但预处理器在扩展此宏时遵循哪些步骤呢?


你对我的回答不满意吗? - Étienne
@Étienne 已修复。谢谢您的解释,我从中学到了东西。 - Maxim Veksler
谢谢,很高兴能够帮到你 ;) - Étienne
2个回答

3

初始情况:

f (1
#undef f
#define f 2
f)

如果我们参考你提供的链接,这个宏被预处理分为两步:

第一步:参数预扩展

如果在宏调用中,该宏被重新定义,则新定义将在参数预扩展时生效。

将作为函数式宏参数使用的 f 替换为 2:

f(1 f) -> f (1 2)

步骤二:参数替换

但原始定义仍用于参数替换。

使用其原始定义对类似函数的宏f进行解析:

f(1 2) -> 1 2 1 2

整个事情实际上等同于以下内容:
#define f(x) x x  
#define g 2
f(1 g)

0

我认为发生的事情如下,为了更好地可视化步骤,让我们通过添加区分括号来重写#define语句。

步骤0

#define f(x) (x) [x]

f (1
#undef f
#define f 2
f)

// 注意,这不是一个有效的 C 代码。我只是在玩弄它以了解预处理器所采取的操作,而不是为了编译它。通过产品 > 操作 > 预处理,可以查看预处理器的结果,就像我上面展示的那样。

因此,预处理器采取的第一步是替换,x 被替换为语句中提供的值(在本例中为“1”),宏值中有 2 次 x,因此相同的替换发生两次。() 和 [] 括号在此处有助于区分两个路径:

步骤 1

(1
#undef f
#define f 2
f) [1
    #undef f
    #define f 2
    f]

然后 #undeff,它确实存在,并将其重新定义为 f 2

步骤2

(1 f) [1 f]

在最后一步,执行一个简单的替换,将f替换为它当前所携带的值,即2

第三步

(1 2) [1 2]

就是这样。期望的结果1 2 1 2已经被替换到了底层。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接