In standard C++ up to and including the 2014 edition of the standard, the expression i = i++
has undefined behavior, because the object i
is modified twice and the two modifications are unsequenced.
The 2017 edition (C++17) made some changes in the description of expression evaluation. An example in C++17 4.6 [intro.execution] says:
void g(int i) {
i = 7, i++, i++; // i becomes 9
i = i++ + 1; // the value of i is incremented
i = i++ + i; // the behavior is undefined
i = i + 1; // the value of i is incremented
}
A lot of people reading that code are going to assume that the behavior of i = i++
is undefined. In fact, if your compiler implements C++17 correctly (and you invoke it in a way that tells it to conform to C++17, for example -std=c++17
for gcc or clang), then the value of i
after the assignment will be 5
. But for a compiler conforming to an older version of C++, or invoked in a non-conforming mode, the behavior is still undefined.
I'll note that g++ -std=c++17 -Wall
(built from the latest gcc sources about a week ago) still warns that i = i++
may be undefined, though running a program still produces the C++17-correct result.
Most likely the compiler you're using does not conform to C++17.
More generally, there's really no good reason to write i = i++
except as a test of compiler conformance. In a conforming C++17 (or later) compiler, it does nothing. Evaluating i++
yields the previous value of i
and, as a side effect, updates i
-- but the updated value is overwritten by the assignment.
(In C, i = i++
still has undefined behavior.)
(I welcome comments from anyone who has read the C++14 and C++17 standards and can cite the normative text that implies this change.)