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.)