#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;
}
答案 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 + B
而B
不会再次展开(如果是,则会有无限递归)。因此编译器在预处理器完成后会看到对未声明变量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代码