嵌套宏的扩展,从内到外?

时间:2015-07-09 03:16:45

标签: c++ c macros c-preprocessor

我偶然发现了这本书 C:从理论到实践,p.436:

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

但我认为它从外到内扩展。我一直都错了吗?

例如,您有宏#define FUNC(x,y) x+y#define PARA 3,4,但无法使用FUNC(PARA)。我认为FUNCPARA之前得到了扩展。

同样,当您执行#define str(s) #s之类的字符串化时,使用str(__LINE__)会导致"__LINE__"

我很困惑。

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

1 个答案:

答案 0 :(得分: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行中,我使用花括号{}来标记嵌套宏的扩展。括号[]中的数字是扩展期间的嵌套级别。下一个括号显示当前展开的宏的名称。

在下降到最里面的嵌套宏时,预处理器知道它当前尝试扩展的宏,并且不会尝试嵌套它们,以避免递归扩展。