Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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 :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Consider exactly when the post-decrement happens. In the second case, obviously the insert happens, modifying the list itself. The iterator is still valid, pointing now at the second entry. Then the decrement is computed, moving the iterator to the first entry.

In the first case, however, the post-decrement "makes a copy" of the iterator, performs the decrement, and returns the previous version. That means that the new value of the iterator is computed before the insert happens, which is invalid since it already points at the first element. Note that the insert still happens correctly, because the post-decrement returns the original and still-valid iterator.

This is not about post- vs. pre- decrement behavior. It’s about when the side-effect of the decrement actually happens. See https://en.cppreference.com/w/cpp/language/eval_order, specifically

  1. When calling a function (whether or not the function is inline, and
    whether or not explicit function call syntax is used), every value
    computation and side effect associated with any argument expression,
    or with the postfix expression designating the called function, is
    sequenced before execution of every expression or statement in the
    body of the called function.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading