当我运行以下代码时,
#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'
有人可以解释输出吗?
答案 0 :(得分:6)
这是因为宏的期望和参数,因为它用括号定义。 您需要将其定义为
#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
文件进行跟踪。
答案 1 :(得分:5)
如果宏被保留为无效的类函数宏,则它们根本没有扩展,因为你没有用括号调用它。所以X永远不会被预处理器替换为任何东西,并且是示例代码中Undefined symbol 'X'
的原因。
如果你想扩展它,你必须用括号来调用它:
printf("%d",4*X()+2);
虽然预处理为4+Y
并且X+3
不是有效的宏参数名称,但这只会出错。
如果您的答案有所纠正,那么这些定义是正确的定义,而不是类似函数的宏,即:
#define X (4+Y)
#define Y (X+3)
您在定义...
之间有一个循环引用X - &gt; Y - &gt; X ......等等。
因为它只会扩展一次宏,所以它会扩展到
printf("%d",4*(4+(X+3))+2);
这解释了为什么X是此用例中未定义的符号。
答案 2 :(得分:1)
你错过了空间
#define X (4+Y)
#define Y (X+3)