预处理器宏如何工作?

cir*_*mbo 6 c macros c-preprocessor

#define B 100+B
main()
{
    int i= B;
}
Run Code Online (Sandbox Code Playgroud)

我知道这是错的,但出于好奇,当我编译它时,我得到了这个奇怪的错误:

"B未在此范围内宣布".

为什么会这样?如果这个错误是因为编译器在替换后删除了宏,那么当BA可用之前必须被删除时,下面的代码是如何工作呢?

#define B 100
#define A 100+B
main()
{
    int i= B;
    int j =A;
}
Run Code Online (Sandbox Code Playgroud)

Kar*_*ath 14

这是预处理器的输出:

gcc -E x.c
# 1 "x.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "x.c"

main()
{
    int i= 100+B;
}
Run Code Online (Sandbox Code Playgroud)

如你所见,它做了替代品.现在,编译步骤失败,因为没有B声明.

其他代码很好,这是输出:

main()
{
    int i= 100;
    int j =100+100;
}
Run Code Online (Sandbox Code Playgroud)

  • *预处理器*,而不是*预编译器* (5认同)

Dan*_*her 9

宏扩展不是递归完成的,如果宏名称出现在替换文本中,则不会再次展开.所以

#define B 100 + B
Run Code Online (Sandbox Code Playgroud)

替换B产生令牌序列100 + B并且B不再扩展(如果是,你将有无限递归).因此编译器B在预处理器完成后会看到对未声明变量的引用.

但在

#define B 100
#define A 100 + B
Run Code Online (Sandbox Code Playgroud)

A扩展宏时,宏名称将B出现在替换文本中.然后B展开,编译器看到100 + 100哪个不包含对未声明变量的引用.

  • 这个答案应该打勾.只是在说'. (2认同)