简体   繁体   English

C 预处理器如何工作?

[英]How C preprocessor works?

How does the C Preprocessor handle multiple macros? C预处理器如何处理多个宏? 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;    
}

on gcc, generates preprocessor.i like this:在 gcc 上,像这样生成 preprocessor.i:

# 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.那么所有这些是如何发生的。

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;因此,预处理器首先将ABC转为int ABC; into int xYz;进入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. ,然后它将xYz转回ABC ,但没有进一步的转换可能,因为这两个宏都被使用过一次。

The second code behaves correctly too, of course.当然,第二个代码的行为也正确。 The int ABC; int ABC; is turned directly into int kkk;直接变成int kkk; . . The int xYz; int xYz; is turned into int ABC;变成int ABC; and then into int kkk;然后进入int kkk; . .

You can look at How many passes does the C preprocessor make?你可以看看C预处理器做了多少遍? for some more information.了解更多信息。

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?预处理器是否一一进行宏替换,例如先完成与#define ABC xYz对应的扩展,然后再进行#define xYz ABC ,还是#define xYz ABC处理两个宏? If the first is the case then the output should be int ABC and int ABC .如果是第一种情况,则输出应为int ABCint ABC

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.当它完成重新扫描替换文本时,所有“已使用”的宏都会再次标记为“未使用”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM