我不明白为什么结果会是 36。有人可以向我解释这里发生了什么以及预处理器做了什么吗?
#include <iostream>
#define QUADRAT(x) ((x) * (x))
using namespace std;
int main()
{
double no = 4.0;
double result = QUADRAT(++no);
cout << result;
return 0;
}
非常感谢 :>
我不明白为什么结果会是 36。有人可以向我解释这里发生了什么以及预处理器做了什么吗?
#include <iostream>
#define QUADRAT(x) ((x) * (x))
using namespace std;
int main()
{
double no = 4.0;
double result = QUADRAT(++no);
cout << result;
return 0;
}
非常感谢 :>
在该示例中,预处理器将替换QUADRAT(++no)
为。((++no) * (++no))
no
如果不是因为两个增量之间没有序列点,那将增加两次,因此您实际上会导致未定义的行为。你看到的任何输出都是有效的,因为没有人知道会发生什么。
预处理器基本上是一个复制粘贴引擎。请注意,宏不是函数;相反,它是内联扩展的。考虑当宏展开时您的代码会发生什么。
这一行:
double result = QUADRAT(++no);
扩展为:
double result = ((++no) * (++no));
最终运行的方式相当于:
no = no + 1;
no = no + 1;
result = no * no;
它以这种方式运行,因为增量是在乘法之前执行的:预处理器对您传递的内容进行文本复制,因此它复制“++no”,以便它在最终代码中出现两次,并且每个增量++no 在计算结果之前发生。解决这个问题的方法是使用内联函数:
inline double QUADRAT(double x) { return x * x; }
大多数现代编译器会在不进行文本替换的情况下扩展此代码 - 它们会为您提供与预处理器定义一样快的东西,但不会有遇到您面临的问题的危险。
发生的是一种用 ++no 代替 x 的文字替换,就像你写的那样:
double result = ((++no) * (++no));
结果是什么......它应该是未定义的行为(你偶然得到 36),并且带有 -Wall 的 g++ 同意我的观点。