Reputation: 14413
#include <iostream>
using namespace std;
struct X
{
int i_Val;
X(int iVal)
:i_Val(iVal)
{
}
X& operator++()
{
cout << "X::operator++()" << endl;
++i_Val;
return *this;
}
operator int() const
{
return i_Val;
}
};
const X operator+(const X& lhs, const X& rhs)
{
cout << "operator+(const X&, const X&)" << endl;
return lhs.i_Val + rhs.i_Val;
}
int main()
{
X x = 5;
X y = (++x) + (++x) + (++x);
cout << y << endl;
}
compile and run. It produces the output:
X::operator++()
X::operator++()
X::operator++()
operator+(const X&, const X&)
operator+(const X&, const X&)
24
But I expected this:
X::operator++()
X::operator++()
operator+(const X&, const X&)
X::operator++()
operator+(const X&, const X&)
22
Who's at blame? Me or the compiler?
Upvotes: 0
Views: 155
Reputation: 146940
This is not undefined behaviour or a dupe of some i++ = ++i
misery, because an overloaded operator is a function call and an implicit sequence point is introduced.
However, it's my understanding that the order of evaluation in this context is unspecified and the compiler is free to re-order this however it likes.
Upvotes: 4
Reputation: 5262
The produced output is more sound mathematically. Do everything in all parentheses once left to right, then do the parent operation.
Upvotes: 0
Reputation: 13541
DeadMG gave the right answer.
If you like to get a 22 you can try a different compiler. ;)
icc gives me your desired output and the gcc produces the 24.
Upvotes: 0