'Why does "L.insert(it--, i);" behave differently from "L.insert(it, i); it--;"?

These are two pieces of code that I ran under the C++11 standard. I expected the post-decrement of the iterator to produce the same effect, but these two pieces of code produce completely different results. Where is my understanding off?

list<int> L;

int main() {    
    L.push_back(0);
    L.push_front(1);
    auto it = L.begin();
    for (int i = 2; i <= 5; i++) {
        L.insert(it--, i);
    }
    for (auto num : L) {
        printf("%d ", num);
    }
    // 2 5 0 4 1 3
}
list<int> L;

int main() {    
    L.push_back(0);
    L.push_front(1);
    auto it = L.begin();
    for (int i = 2; i <= 5; i++) {
        L.insert(it, i);
        it--;
    }
    for (auto num : L) {
        printf("%d ", num);
    }
    // 5 4 3 2 1 0
}


Solution 1:[1]

L.insert(it, i);
it--;

This inserts a node before it, then moves it backwards to the inserted node.

L.insert(it--, i);

The order of operations is swapped: it moves the iterator backwards before insert() is called. There's no node to move back to so it causes undefined behavior.

Solution 2:[2]

Your code invokes undefined behaviour.

The begin iterator is not decrementable and the behavior is undefined if --container.begin() is evaluated.

https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator

As such, anything could happen.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Kugelman
Solution 2 Jeffrey