从内部到外部展开嵌套宏

Expansion of nested macros, from the inner to the outer?

本文关键字:嵌套 外部 内部      更新时间:2023-10-16

我在C:从理论到实践,第436页:

"预处理器将嵌套宏从内部扩展到外部。"

但我认为它是由外向内扩展的。难道我一直都错了吗?

例如,您有#define FUNC(x,y) x+y#define PARA 3,4宏,但不能使用FUNC(PARA)宏。我认为FUNC会在PARA之前展开。

同样,当您执行像#define str(s) #s这样的字符串化时,使用str(__LINE__)会得到"__LINE__"

我困惑。

如果嵌套宏从内部扩展到外部,那么如何理解这2个例子?

答案是这些不是嵌套的宏,而是参数中的宏。可能会有一些混淆,因为一些来源仍然将它们称为"嵌套"宏。但实际上,参数稍后会展开。

嵌套宏是在另一个宏的替换列表中的宏。在包含它们的宏展开之前展开它们。

参见示例:

#define foo "foo" bar baz
#define bar "bar" baz foo
#define baz "baz" foo bar
foo
bar
baz

导致以下展开:

"foo" "bar" "baz" foo bar foo "baz" foo "bar" baz foo
"bar" "baz" "foo" bar baz bar "foo" bar "baz" foo bar
"baz" "foo" "bar" baz foo baz "bar" baz "foo" bar baz

发生了什么(只详细解释第一行)?

1.  [1][foo] bar is found -> expand this first
2.  [2][bar] baz is found -> expand this first
3.  [3][baz] foo is found -> already in "foo" expansion, ignore
4.  [3][baz] bar is found -> already in "bar" expansion, ignore
5.  [3][baz] baz expands to ["baz" foo bar]
6.  [2][bar] foo is found -> already in "foo" expansion, ignore
7.  [2][bar] bar expands to ["bar" "baz" foo bar foo] <- note baz was expanded before bar
8.  [1][foo] baz is found -> expand this first
9.  [2][baz] foo is found -> already in "foo" expansion, ignore
10. [2][baz] bar is found -> expand this first
11. [3][bar] baz is found -> already in "baz" expansion, ignore
12. [3][bar] foo is found -> already in "foo" expansion, ignore
13. [3][bar] bar expands to ["bar" baz foo]
14. [2][baz] baz expands to ["baz" foo "bar" baz foo] <- note bar was expanded first
15. [1][foo] foo expands to ["foo" { "bar" "baz" foo bar foo } { "baz" foo "bar" baz foo } ]

注意:在第15行中,我使用花括号{}来标记嵌套宏的展开。括号[]中的数字是展开时的嵌套级别。下一个括号显示当前展开的宏的名称。

当下降到最内层的嵌套宏时,预处理器知道它当前尝试展开的宏是什么,并且不尝试嵌套展开它们,以避免递归展开。