Why post-increment needs to make a copy while pre-increment does not

2.9k views Asked by At

I know this issue has been discussed several times , but I could not find a post which explains why a copy needs to be made in case of a post-increment operation.

Quoting from a stackoverflow reply:

int j = i++; // j will contain i, i will be incremented.
int j = ++i; // i will be incremented, and j will contain i+1.

Which perfectly makes sense when the definition of post/pre increment is considered. Many times when comparing the performance of pre/post increment it is said that post increment needs to make a copy, increment it and return the copy while pre-increment just increases value and does not create a copy.

Although performance has been compared in tens of posts, I really could not find any explanation on why a copy has to be made in the case of post-increment. Why doesn't it return the old value and then increments the value of the variable by one(or however way operator is overloaded), rather than creating a new object and return that one.

3

There are 3 answers

0
NathanOliver On BEST ANSWER

The difference is someval++ returns what someval is before the increment and to do that you need remember what someval is with a copy. How else would you return the original value while updating it if the original value wasn't stored somewhere?

0
Antwane On

Consider pre-incrementation and post-incrementation operators as standard functions:

// ++i
int pre_increment(int &i) {
    i = i + 1;
    return i;
}

// i++
int post_increment(int &i) {
    int original_i = i;
    i = i + 1;
    return original_i;
}

This should help you to understand why in the second case (i++), you MUST perform a copy of the value before doing the incrementation.

0
R Sahu On

It's hard for me to say how compilers can optimize the pre-increment and post-increment operators so that a copy is not necessarily made on primitive types.

I can show how a copy needs to be made for user defined types for the post-increment operators.

Lets' take a simplistic look at std::vector::iterator.

Let's say the iterator stores an index, in addition to the other things.

struct iterator
{
   size_t index;

   iterator operator++(int )
   {
      iterator copy = *this;
      this->index++;
      return copy;
   }
 };

In such a case, it is not possible to return *this first and then increment the index. Creating a copy, incrementing the index of this, and then returning the copy allows us to preserve the semantics of that operation.