The book implies the following is ambigous |
The book is too gentle: any program which contains that code is entirely wrong.
If there is a clear priority list, it should be obvious what happens. |
Operator precedence and
associativity doesn't have anything to do with
order of evaluation.
Imagine I asked you to compute the following value:
(0.1 * 2.3) / (4.5 * 6.7) * (8 * 9)
Operator precedence does not compel you to evaluate all the parts of the problem in any particular order. If you so chose, you might compute the term (8 * 9) first, even though according to the binding order it's the "lowest-priority" term. Alternatively, you might attempt to simplify by computing
(0.1 * 2.3) and
(8 * 9) first, and then multiplying them - again, this doesn't concern operator precedence - it won't make any difference to the result.
The only thing operator precedence tells you is which operands belong to which operators.
Similarly, C++ offers limited guarantees regarding the evaluation order of terms (more specifically
expressions and
sub-expressions). In the case of the example you gave, there are no guarantees that the side effect implied by
i++ happens before the side-effect implied by the assignment. That might happen before or after, or even
in the middle of the assignment operation. In the jargon, we would say that such an expression implies two
unsequenced side effects relative to the same object. This is undefined behavior.
Well, until C++17, which offers this guarantee:
_{In every simple assignment expression E1=E2 and every compound assignment expression E1@=E2, every value computation and side-effect of E2 is sequenced before every value computation and side effect of E1.
}