C 预处理器如何工作,例如处理多个宏?

问题描述 投票:0回答:1

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;
}

那么这一切是如何发生的呢?

c gcc c-preprocessor
1个回答
4
投票

第一种情况的行为是正确的,因为一旦在扩展中使用了一次宏,就不能再次使用。因此,预处理器首先将

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

宏定义的顺序并不重要。预处理器对输入进行标记,对于每个符号,它都会查看是否定义了宏。如果有宏,它会应用宏扩展,然后将其标记为“已使用”(对于当前令牌扩展)。然后,它重新扫描替换文本,再次查找标记,并再次应用宏(除非它们被标记为“已使用”)。 “标记为已使用”可防止宏扩展中的无限递归。当它完成重新扫描替换文本时,所有“已使用”的宏将再次标记为“未使用”。

© www.soinside.com 2019 - 2024. All rights reserved.