几天前我见过的那个小而且非常讨厌的问题,在接受采访时问我的朋友.
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.
所以,我有点失落:)
解决方法
The initial interview question was: “What will be the output of the following code?”
int i = 2; i = i++ + i++;
正确答案是undefined behaviour,因为您正在多次修改同一个变量,而中间没有序列点.
C 03标准§5[expr] p4:
Except where noted,the order of evaluation of operands of individual operators and subexpressions of individual expressions,and the order in which side effects take place,is unspecified.
这可能无法解答您的真实问题,但即使您创建类似整数的类并重载运算符(int)和运算符(A const&),它也会类似.函数的参数的评估顺序是未指定的,它可以按编译器喜欢的任何顺序完成,因此结果未指定.