当我运行以下代码时,
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("%d",4*X+2);
return 0;
}
I am getting the following output:
Error: Undefined symbol 'X'
有人可以解释一下输出吗?
当我运行以下代码时,
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("%d",4*X+2);
return 0;
}
I am getting the following output:
Error: Undefined symbol 'X'
有人可以解释一下输出吗?
这是因为宏期望和参数,因为它用括号定义。您需要将其定义为
#define X 4+Y
和#define Y X+3
。然后你会因为宏中的循环定义而遇到另一个麻烦。
正如德鲁建议的那样,更正确的是;当定义宏时示例可编译时,通常将括号放在表达式周围以确保预期的运算符优先级。
所以你最好的镜头是:
#define X (4+Y)
#define Y (X+3)
非常接近您的初始示例,只是宏名称与其定义之间的空格字符。但是,由于循环引用,仍然无法正确扩展宏。
如何检查发生了什么:
您可以使用gcc -E
,它输出一个预处理文件。它会产生大量输出,所以我使用了tail
. 我也曾经2>err
将错误流重定向到一个文件,所以输出很清楚。
luk32:~/projects/tests$ gcc -E ./cyclic_macro_with_no_spaces.c 2> err | tail -n 6
int main()
{
printf("%d",4*X+2);
return 0;
}
luk32:~/projects/tests$ gcc -E ./cyclic_macro.c 2> err | tail -n 6
int main()
{
printf("%d",4*(4+(X+3))+2);
return 0;
}
在第一个示例中,X
根本没有扩展。而在后者中,两个宏都得到了扩展,尽管只有一个。给出与杰弗里在他的回答中提出的相同的输出。
无论没有空格是错字还是有undefined symbol 'X'
. 出于不同的原因,可以通过分析err
文件进行跟踪。
如果宏被保留为无效的类函数宏,它们根本不会被扩展,因为你没有用括号调用它。所以 X 永远不会被预处理器替换为任何东西,这就是Undefined symbol 'X'
您的示例代码中出现的原因。
如果你想扩展它,你必须用这样的括号来调用它:
printf("%d",4*X()+2);
但是,当预处理为4+Y
并且X+3
不是有效的宏参数名称时,这只会出错。
如果您的答案有所纠正,以便这些定义是正确的定义,而不是类似函数的宏,即:
#define X (4+Y)
#define Y (X+3)
您在定义之间有一个循环引用...
X -> Y -> X... 等等。
由于它只会扩展一次宏,因此它正在扩展为
printf("%d",4*(4+(X+3))+2);
这就解释了为什么 X 在这个用例中是未定义的符号。
你错过了空间
#define X (4+Y)
#define Y (X+3)