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

标签 c++ c macros c-preprocessor

我在《C:从理论到实践》一书中偶然发现了这句话,第 436 页:

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

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

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

类似地,当您进行诸如 #define str(s) #s 之类的字符串化时,使用 str(__LINE__) 会产生 "__LINE__" .

我很困惑。

如果嵌套宏是从内向外展开的,那么这两个例子怎么理解?

最佳答案

答案是这些不是嵌套宏,而是参数中的宏。可能会出现一些困惑,因为一些消息来源仍然将它们称为“嵌套”宏。但确实,参数是后来扩展的。

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

参见示例:

#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 行,我使用大括号 {} 来标记嵌套宏的扩展。括号[]中的数字是展开时的嵌套层数。下一个括号显示当前扩展的宏的名称。

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

关于c++ - 嵌套宏的扩展,从内到外?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31307503/

相关文章:

c++ - 为 OS X 10.6 编译?

c++ - 使用 clang : AST differences in when including a header in another source file or parsing it directly 解析命名空间

c++ - clang 似乎没有链接到库

c - 在 C/C++ 中使用 libcurl 下载文件

macros - 在 yacc/bison lex 中处理#define 宏

c++ - 通过引用传递的特征参数

c - 问题查找字符串中给定子字符串的出现次数

c - fopen 创建新文件始终为大写

c - 为什么我不能声明一个已经定义了结构的变量?

macros - `amb` 运算符是宏还是过程?