Precedence of post and pre incrementation operators
There is code:
#include <iostream>
class Int {
public:
Int() : x(0) {}
Int(int x_) : x(x_) {}
Int& operator=(const Int& b) {
std::cout << "= from " << x << " = " << b.x << std::endl;
x = b.x;
}
Int& operator+=(const Int& b) {
std::cout << "+= from " << x << " + " << b.x << std::endl;
x += b.x;
return *this;
}
Int& operator++() {
std::cout << "++ prefix " << x << std::endl;
++x;
return *this;
}
Int operator++(int) {
std::cout << "++ postfix " << x << std::endl;
Int result(*this);
++x;
return result;
}
private:
int x;
};
Int operator+(const Int& a, const Int& b) {
std::cout << "operator+" << std::endl;
Int result(a);
result += b;
return result;
}
int main() {
Int a(2), b(3), c(4), d;
d = ++a + b++ + ++c;
return 0;
}
Result:
++ prefix 4
++ postfix 3
++ prefix 2
operator+
+= from 3 + 3
operator+
+= from 6 + 5
= from 0 = 11
Why postfix operator isn't execute开发者_Go百科d before prefix operator (++ prefix 4) altough priority of postfix operator is higher than prefix operator?
This was compiled by g++.
The order of evaluation of the different operands is unspecified which means that the compiler is free to reorder the evaluation of the ++a
, b++
and ++c
subexpressions as it pleases. The precedence of the operators does not really have any impact in that example.
It does have an effect if you try to write ++i++
(where i
is an int
) which will be grouped as ++(i++)
and it will fail to compile as the subexpression i++
is an rvalue and prefix increment requires an lvalue. If the precedence was reversed, then that expression would compile (and cause Undefined Behavior)
Postfix ++
has the highest precedence in the expression ++a + b++ + ++c
, but +
has the lowest precedence and is left associative. This expression can be equivalently written as (++a) + (b++) + (++c)
(each ++
is part of a different subexpressions) which explains why ++a
is evaluated first. Consider traversing/evaluating the corresponding parse tree and it becomes obvious what the order of evaluation:
E
/ | \
/ | E
/ | | \
E + ++ c
/ | \
/ | \
E + E
/ \ / \
++ a b ++
精彩评论