C预处理程序如何工作?

迪潘卡·辛格(Deepankar Singh)

C预处理器如何处理多个宏?我也在这里和Google上进行了搜索,但无法理解应遵循的确切规则。如下代码:

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

那么所有这些都是如何发生的。

乔纳森·勒夫勒(Jonathan Leffler)

第一种情况下的行为是正确的,因为一旦在扩展中使用了宏一次,就无法再使用它。因此,预处理器首先将ABCinint ABC;转换为int xYz;,然后将其xYz转换为ABC,但是由于两个宏都已使用一次,因此无法进行进一步的转换。

当然,第二个代码的行为也正确。int ABC;直接变成int kkk;int xYz;变成int ABC;再进int kkk;

您可以看一下C预处理程序进行多少遍?有关更多信息。

预处理程序是一个接一个地进行宏替换吗,就像首先#define ABC xYz完成对应的扩展然后转到#define xYz ABC,还是一次性处理两个宏?如果是第一种情况,则输出应为int ABCint ABC

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C预处理程序实际上是如何工作的?

来自分类Dev

C预处理程序实际上是如何工作的?

来自分类Dev

#define预处理程序如何真正在C中工作

来自分类Dev

C预处理程序如何处理循环依赖关系?

来自分类Dev

如何为C#预处理程序符号定义值?

来自分类Dev

如何使用C预处理程序找到glibc版本?

来自分类Dev

如何定义C#预处理程序符号的值?

来自分类Dev

如何预处理ld链接程序脚本?

来自分类Dev

如何预处理ld链接程序脚本?

来自分类Dev

C预处理程序指针混乱

来自分类Dev

#define之外的C预处理程序串联

来自分类Dev

for循环中的C预处理程序串联

来自分类Dev

C预处理程序是否在运行?

来自分类Dev

扩展单个C预处理程序指令

来自分类Dev

C预处理程序是否删除“&*”的实例?

来自分类Dev

C预处理程序:及早评估宏

来自分类Dev

C ++预处理程序串联操作

来自分类Dev

C预处理程序删除结尾的逗号

来自分类Dev

C预处理程序宏扩展串联

来自分类Dev

C中的预处理程序指令

来自分类Dev

C预处理程序宏多个参数

来自分类Dev

C预处理程序的默认添加

来自分类Dev

C预处理程序指令和链接

来自分类Dev

解释C预处理程序代码

来自分类Dev

C预处理程序宏扩展串联

来自分类Dev

C预处理程序:动态#Define创建

来自分类Dev

C预处理程序是否在运行?

来自分类Dev

C / C ++:预处理器指令应如何在宏参数列表上工作?

来自分类Dev

如何部分预处理具有特定工作目录的 C 文件