The problem is one of
evaluation order, not operator precedence: it cannot be corrected by adding parentheses.
The problem is easier to see once some extraneous variables are removed:
1 2 3 4 5 6
|
int main()
{
int a = 3;
a = a++ - 3;
std::cout << a;
}
| |
Since C++17: the output is 0. The value computation and side-effects of the left operand of the assignment are
sequenced-before the side-effects of the assignment expression.
(e.g.
a = a++ leaves
a unchanged: the compiler is required to carry out the side-effects of
a++ before assigning the value of
a++ to
a).
Before C++17: the behavior is undefined. The value computation but
not the side-effects of the left operand of the assignment are
sequenced-before the side-effects of the assignment expression. Therefore two modifications to
a are unsequenced, resulting in undefined behavior.
https://en.cppreference.com/w/cpp/language/eval_order
(e.g.,
a = a++ has undefined behavior because the compiler is not required to carry out the side effects of
a++ before assigning the value of
a++ to
a. The assignment could happen first, in which case
a would be incremented. Or the increment could happen first, in which case
a would be left unchanged. Or, in theory, evaluation of the side-effects could be interleaved, resulting in unpredictable behavior.)