预处理器宏如何工作?

时间:2012-08-05 18:05:11

标签: c macros c-preprocessor

#define B 100+B
main()
{
    int i= B;
}

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

  

“B未在此范围内宣布”。

为什么会这样?如果此错误是因为编译器在替换后删除了宏,那么当 B B 可用之前必须删除它时,以下代码如何正常工作?

#define B 100
#define A 100+B
main()
{
    int i= B;
    int j =A;
}

3 个答案:

答案 0 :(得分:14)

这是预处理器的输出:

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

main()
{
    int i= 100+B;
}

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

其他代码没问题,这是输出:

main()
{
    int i= 100;
    int j =100+100;
}

答案 1 :(得分:9)

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

#define B 100 + B

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

但是在

#define B 100
#define A 100 + B

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

答案 2 :(得分:0)

宏替换是简单的文本操作。您可以通过简单的逐步编译来调试此类问题。

使用cc -E filename.c -O filename.i

用于生成扩展c代码

vi filename.i用于读取纯/扩展c代码