C 定义主体是另一个定义

C 定义主体是另一个定义,c,c-preprocessor,C,C Preprocessor,我无法明确地找到这个问题的答案,但在实践中似乎有效: // example #1 #define test 5 #define test2 test (test2==5)==true 即使这样: // example #2 #define test2 test #define test 5 是否有明确的C规范规则允许这样做。我认为预处理器非常简单,它只是查找/替换。但我猜在#define test2 test的情况下,它知道test不是字符串,所以它可能是define?那么预处理器只对这种类

我无法明确地找到这个问题的答案,但在实践中似乎有效:

// example #1
#define test 5
#define test2 test
(test2==5)==true

即使这样:

// example #2
#define test2 test
#define test 5
是否有明确的C规范规则允许这样做。我认为预处理器非常简单,它只是查找/替换。但我猜在
#define test2 test
的情况下,它知道test不是字符串,所以它可能是
define
?那么预处理器只对这种类型的场景进行多次扫描


我的主要问题是,为什么我的示例#2有效?

如何处理第一个:

#define test 5
#define test2 test
something with test
something with test2

#define test2 5
something with 5
something with test2

something with 5
something with 5
#define test2 test
#define test 5
something with test
something with test2

#define test 5
something with test
something with test

something with 5
something with 5
如何处理第二个问题:

#define test 5
#define test2 test
something with test
something with test2

#define test2 5
something with 5
something with test2

something with 5
something with 5
#define test2 test
#define test 5
something with test
something with test2

#define test 5
something with test
something with test

something with 5
something with 5

预处理结果如下:

#define test2 test
#define test 5

test2
test
给出:

5
5
即使在
test2
之后定义了
test
。预处理器将按照中的指定重新扫描源:

(C99,6.10.3.4重新扫描和进一步替换p1)“替换列表中的所有参数被替换并且#和##处理完成后,移除所有placemarker预处理标记。然后重新扫描生成的预处理标记序列以及所有后续标记 预处理源文件的标记,以替换更多宏名称。“


它只是按照
#define
的编写顺序查找/替换。所以,这是预期的行为。“它知道测试不是字符串”-预处理器除了文本替换之外什么都不知道。@EdCottrell,参见我的示例#2。其中首先定义test2。当我打印test2时,为什么结果是5?定义的顺序将打破示例#2。想想看。如果您计算
test2==5
并将
test2
替换为
test
,然后将
test
替换为
5
,您得到了什么?
#define
s是按顺序计算的,但这并不意味着其中使用的所有值必须已经是
#define
d.@edcontrolell因此在每个define上,它都会重新扫描整个文件。