C 预处理器如何处理多个宏?我在这里和谷歌上也进行了搜索,但我无法理解应该遵循的确切规则。代码如下:
#define ABC xYz
#define xYz ABC
int main()
{
int ABC;
int xYz;
}
在 gcc 中,生成文件 preprocessor.i,如下所示:
# 1 "preprocessor.c"
# 1 "<command-line>"
# 1 "preprocessor.c"
int main()
{
int ABC;
int xYz;
}
这里似乎没有任何内容被替换。和其他代码:
#define ABC kkk
#define xYz ABC
int main()
{
int ABC;
int xYz;
}
生成如下输出:
# 1 "preprocessor.c"
# 1 "<command-line>"
# 1 "preprocessor.c"
int main()
{
int kkk;
int kkk;
}
那么这一切是如何发生的呢?
第一种情况的行为是正确的,因为一旦在扩展中使用了一次宏,就不能再次使用。因此,预处理器首先将
ABC
中的 int ABC;
转换为 int xYz;
,然后将 xYz
重新转换为 ABC
,但无法进行进一步的转换,因为这两个宏都已使用过一次。
当然,第二个代码的行为也正确。
int ABC;
直接变成了int kkk;
。 int xYz;
变成 int ABC;
,然后变成 int kkk;
。
您可以查看C 预处理器进行了多少遍?以获取更多信息。
预处理器是否会逐一进行宏替换,例如首先完成与
对应的扩展,然后再进行#define ABC xYz
,还是一次性处理两个宏?如果是第一种情况,那么输出应该是#define xYz ABC
和int ABC
。int ABC
宏定义的顺序并不重要。预处理器对输入进行标记,对于每个符号,它都会查看是否定义了宏。如果有宏,它会应用宏扩展,然后将其标记为“已使用”(对于当前令牌扩展)。然后,它重新扫描替换文本,再次查找标记,并再次应用宏(除非它们被标记为“已使用”)。 “标记为已使用”可防止宏扩展中的无限递归。当它完成重新扫描替换文本时,所有“已使用”的宏将再次标记为“未使用”。