Let say i is equals to 5.
On high level there can be two possibilities:
1) i is evaluated (5 is stored as result) i is incremented (i is now 6) i is assigned stored value (i is now 5)
2) i is evaluated (5 is stored as result) i is assigned stored value (i is now 5) i is incremented (i is now 6)
If we take into account actual processor workings, that i can be not only int but any type with complex inrement operator, we will find out that we cannot really know what i can be.
C++ Standard does not standartise any behavior, giving compiler ability to generate efficient code (say by caching values). In some languages order is standartised (JAVA) in some not.
in the line i = i++; you evaluate i, increment i (which involves assigning to i), and finally there is another assignment to i. The order of the increment and assignment is not set out in the standard, so different compilers are free to do what they want, hence the undefined behaviour.
doesn't post increment operator means that the value is used first and then incremented
It doesn't say "first" anywhere. The post increment operator performs two actions: it returns a copy of the old value of the variable and it increments the variable. These actions are independent, they can happen in any order, and other parts of your program can be executing between these two actions, or at the same time (in a single thread: there are plenty of ways to get the CPU to do multiple things with one command)
The only constraint here is that the assignment cannot begin until the post-increment's return value is available, but the assignment doesn't wait for the post-increment's increment to be complete. As a result, if i is a built-in type, you're writing to memory from the assignment and from the postincrement at the same time, unsequenced, and the rules say, since the earliest days of C, that the behavior is undefined in this case (which means the compiler can go wild and do whatever it wants)
If i is a user-defined type, increment and assignment are function calls, and different rules apply, there is no undefined behavior in that case.