C预处理器如何工作? [英] How C preprocessor works?

查看:118
本文介绍了C预处理器如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C 预处理器如何处理多个宏?我在这里搜索了它,也搜索了谷歌,但无法理解应该遵循的确切规则。以下代码:

How does the C Preprocessor handle multiple macros? I searched it over here and google too but not able to understand the exact rule that should be followed. The following code:

#define ABC xYz
#define xYz ABC
int main()
{
    int ABC;
    int xYz;    
}

在gcc上生成预处理器,如下所示:

on gcc, generates preprocessor.i like this:

# 1 "preprocessor.c"
# 1 "<command-line>"
# 1 "preprocessor.c"


int main()
{
 int ABC;
 int xYz;
}

似乎没有任何东西在这里被替换。和其他代码:

seems nothing is replaced here. And other code:

#define ABC kkk
#define xYz ABC
int main()
{
    int ABC;
    int xYz;    
}

产生如下输出:

generates output like this:

# 1 "preprocessor.c"
# 1 "<command-line>"
# 1 "preprocessor.c"


int main()
{
 int kkk;
 int kkk;
}

所以这些都是怎么发生的。

So how all these are happening.

推荐答案

第一种情况下的行为是正确的,因为一旦宏在扩展中被使用一次,再次使用。因此,预处理器首先将 int ABC; 中的 ABC 变成 int xYz; code>,然后将 xYz 变回到 ABC 中,但是没有进一步的转换可能,因为这两个宏都被使用过一次。

The behaviour in the first case is correct because once a macro has been used once in an expansion, it can't be used again. So, the preprocessor first turns the ABC in int ABC; into int xYz;, and then it turns the xYz back into ABC, but there are no further transforms possible because both macros have been used once.

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

The second code behaves correctly too, of course. The int ABC; is turned directly into int kkk;. The int xYz; is turned into int ABC; and then into int kkk;.

你可以看看以获得更多信息。

You can look at How many passes does the C preprocessor make? for some more information.


预处理程序会一个接一个地进行宏替换,如首先完成对应于 #define ABC xYz 的扩展,然后执行 #define xYz ABC ,还是一次处理两个宏?如果第一种情况是这种情况,那么输出应该是 int ABC int ABC

Does the preprocessor do macro substitution one by one, like first the expansion corresponding to #define ABC xYz is done then it goes for #define xYz ABC, or does it handle both macros in one go? If the first is the case then the output should be int ABC and int ABC.

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

The sequence in which the macros are defined is immaterial. The preprocessor tokenizes the input, and for each symbol, it looks to see whether there is a macro defined. If there is a macro, it applies the macro expansion and then marks it as 'used' (for the current token expansion). It then rescans the replacement text, looking for tokens again, and applying macros again (unless they're marked 'used'). The 'marking as used' prevents infinite recursion in macro expansion. When it finishes rescanning the replacement text, all the 'used' macros are marked 'unused' again.

这篇关于C预处理器如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆