2017-02-04 34 views
-2

我有这个功能,它自己添加一个数字。#define ADD(x)(x)+(x)返回错误结果

#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 

#define ADD(x) (x)+(x) 
int main() 
{ 
    int x = 2; 
    int y = ADD(++x); 

    cout << y << endl; 
} 

当我运行这个程序,它会返回8,但我还是希望6.

我想X = 3,这是送3 ADD功能,但现在看来似乎没有。有人可以向我解释吗?

+0

如果您只是调用ADD(2),它会返回什么? –

+2

这是创建内联函数的旧方法。现在尝试不这样做。 –

+1

[C中宏需要括号](http://stackoverflow.com/q/10820340/995714) –

回答

9

程序具有不确定的行为,因为你两次调用前增量操作:int y = (++x)+(++x);。你没有得到编译器警告吗?

问题是ADD不是函数。这是一个宏观;它执行文本替换。不要在C++中使用这些宏。

如果你把宏插入功能,一切都将正常工作,因为那时++x只出现一次:

#include <iostream> 

template <class T> 
T add(T x) 
{ 
    return x + x; 
} 

int main() 
{ 
    int x = 2; 
    int y = add(++x); 

    std::cout << y << '\n'; 
} 
+1

cout << add(++ x)<< endl;'会产生什么结果?而不是将回报存储在'y'中。 – Raindrop7

+0

@ Raindrop7:你为什么问?你试过时是不是打印出“add”的结果? –

+0

谢谢,我现在明白了:) – Berkin

1

这是未定义的行为

当你的编译器在这里预处理宏:

int y = ADD(++x); 

成为

int y = (++x)+(++x); 

存在其中论点评估没有特定的顺序。

欲了解更多信息,请参阅Why are these constructs (using ++) undefined behavior?

+0

协处理器阶段? – Peter

+0

@Peter谢谢你的建议。我做了更正。 – rsp

1

宏是不是真正的C++函数。这只是文字替换。

您的代码:

int y = ADD(++x); 

被替换为:

int y = (++x)+(++x); 

可以使用的,而不是宏观的模板功能。

template<typename T1, typename T2> 
inline auto add(T1 x, T2 y) 
{ 
    return x + y; 
} 
+1

值得一提的是,'auto'返回类型是在C++ 14中引入的,并且不能在C++ 11模式下工作。 –

0

由于ADD(x)实际上是一个宏(而不是一个真正的功能),ADD(++x)计算结果为(++x) + (++x)这是不是很好,因为在所有该修改同一个变量,x,两次在一个声明。这种修改的结果是不确定的。

在你的编译器的特定情况下,从2到3递增x的值,然后增加它的3至4时,以执行(x+x)阅读x的价值,它选择阅读最新值,是4.

我建议你阅读宏和函数之间的区别。

相关问题