我几天前在面试时向我的朋友提出过一个小而令人讨厌的问题。
最初的面试问题是:“以下代码的输出是什么?”
int i = 2;
i = i++ + i++;
正确答案是 ((2 + 2) + 1) + 1 = 6,即后自增在赋值之前应用两次,但在加法之后应用。
然后我想创建一个简单的类,携带一个整数并重载operator+()和operator++(int),以在日志中查看运算符执行的确切顺序。
这就是我得到的:
class A
{
public:
A(int _data) : data(_data) { }
A &operator=(const A& _rhs)
{
data = _rhs.data;
cout<<" -- assign: "<<data<<endl;
}
A operator++(int _unused)
{
A _tmp = data;
data++;
cout<<" -- post-increment: "<<data<<endl;
return _tmp;
}
A operator+(const A &_rhs)
{
A _tmp = data + _rhs.data;
cout<<" -- addition: "<<data<<"+"<<_rhs.data<<endl;
return _tmp;
}
inline operator int() const { return data; }
private:
int data;
};
结果相当令人沮丧:
-- post-increment: 3
-- post-increment: 4
-- addition: 3+2
-- assign: 5
对于不太复杂的结构,例如 (A _dt2 = a++; ),它的行为应该如此,但运算符的执行顺序与整型不同。
我猜这可能是编译器特定的问题:
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
所以,我有点失落:)
最初的面试问题是:“以下代码的输出是什么?”
int i = 2;
i = i++ + i++;
正确答案是未定义的行为 https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points/4176333#4176333,因为您多次修改同一个变量,而中间没有序列点。
C++03标准§5 [expr] p4
:
除非另有说明,否则未指定各个运算符的操作数和各个表达式的子表达式的求值顺序以及副作用发生的顺序。
这可能无法回答您真正的问题,但即使您创建一个类似整数的类并重载,它也会类似operator++(int)
and operator+(A const&)
。函数参数的计算顺序是未指定的,可以按编译器喜欢的任何顺序完成,因此结果是未指定的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)