#define B 100+B
main()
{
int i= B;
}
我知道这是错误的,但出于好奇,当我编译它时,我得到了这个奇怪的错误:
“B 未在此范围内声明”。
为什么会这样?如果此错误是因为编译器在替换宏后删除了宏,那么以下代码如何正常工作,当B必须在对A可用之前被删除时?
#define B 100
#define A 100+B
main()
{
int i= B;
int j =A;
}
#define B 100+B
main()
{
int i= B;
}
我知道这是错误的,但出于好奇,当我编译它时,我得到了这个奇怪的错误:
“B 未在此范围内声明”。
为什么会这样?如果此错误是因为编译器在替换宏后删除了宏,那么以下代码如何正常工作,当B必须在对A可用之前被删除时?
#define B 100
#define A 100+B
main()
{
int i= B;
int j =A;
}
这是预处理器的输出:
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;
}
宏扩展不是递归完成的,如果宏名称出现在替换文本中,则不会再次扩展。所以随着
#define B 100 + B
替换B
产生令牌序列100 + B
并且B
不会再次扩展(如果是,您将有无限递归)。所以编译器会B
在预处理器完成后看到对未声明变量的引用。
但在
#define B 100
#define A 100 + B
当宏A
展开时,宏名称会B
出现在替换文本中。然后B
展开,编译器看到100 + 100
哪些不包含对未声明变量的引用。
宏替换是简单的文本操作。您可以通过简单的逐步编译来调试此类问题。
使用 cc -E 文件名.c -O 文件名.i
用于生成扩展的 c 代码
vi filename.i 用于读取纯/扩展的 c 代码