宏输出说明

时间:2013-07-24 15:27:45

标签: c

当我运行以下代码时,

#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'

有人可以解释输出吗?

3 个答案:

答案 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)