20

My interest is in the difference between for and while loops. I know that the post-increment value is used and then incremented and the operation returns a constant pre-increment.

while (true) {
    //...
    i++;
    int j = i;
}

Here, will j contain the old i or the post-incremented i at the end of the loop?

8 Answers8

49

Since the statement i++ ends at the ; in your example, it makes no difference whether you use pre- or post-increment.

The difference arises when you utilize the result:

int j = i++; // i will contain i_old + 1, j will contain the i_old.

Vs:

int j = ++i; // i and j will both contain i_old + 1.
Jason R. Mick
  • 5,177
  • 4
  • 40
  • 69
zennehoy
  • 6,405
  • 28
  • 55
  • 1
    `int j = ++i; // i will be incremented, and j will contain i+1.` This is false. `j` will still contain `i`, but it is already incremented so there is no need to make it contain `i + 1`. – Tim Nov 21 '15 at 11:07
  • 2
    @Tim "j will contain i+1" refers to the original value of i - admittedly not an ideal formulation. j and i will both have the same value when the statement completes. – zennehoy Nov 21 '15 at 23:00
  • An important exception is when `++i` is mixed w/ other `i` use in complex statments. `printXY(++i, i++)` and `a[i] = ++i` produce pathological results when tested across multiple compilers. The solution is to avoid multiple usage of variables preincremented, or dependent on preincremented values. For instance `a[i] = i;` can be rewritten as `i++; a[i] = i;` for consistency and clarity. See: https://stackoverflow.com/questions/2989704/order-of-operations-for-pre-increment-and-post-increment-in-a-function-argument/2989852#2989852 For more info. – Jason R. Mick Nov 05 '17 at 21:14
  • @JasonR.Mick Absolutely, though I think you have a typo in that second-to-last code snippet (should probably be `a[i] = ++i`). Note though that the actual answer to the question as asked is the first sentence. The rest was just to add a bit more context, and could obviously be expanded. – zennehoy Nov 06 '17 at 08:30
  • @zennehoy Good catch, indeed should have read: ... `a[i] = ++i;` can be rewritten as `i++; a[i] = i;` .... (second copy of `a[i] = ++i;` in the above comment is missing the pre-increment operator). – Jason R. Mick Nov 14 '17 at 14:34
45

Depends on how you use them.

  • i++ makes a copy, increases i, and returns the copy (old value).
  • ++i increases i, and returns i.

In your example it is all about speed. ++i will be the faster than i++ since it doesn't make a copy.

However a compiler will probably optimize it away since you are not storing the returned value from the increment operator in your example, but this is only possible for fundamental types like a int.

isomorphismes
  • 8,233
  • 9
  • 59
  • 70
Tim
  • 5,521
  • 8
  • 36
  • 69
  • Assuming i isn't of class type, it makes no difference in speed. Even for a class type, pre-increment isn't necessarily faster than post-increment, depending on the implementation. – zennehoy Jun 28 '13 at 14:29
  • @zennehoy I hope you mean it the other way around. And even for class types it might be faster to use pre-increment. Like iterators. – Tim Jun 28 '13 at 14:31
  • 1
    Generally, pre-increment will be the same or faster than post-increment (since it shouldn't need to make a copy). Depending on the implementation, it could also be the other way around (though this would probably be a pretty poor implementation). – zennehoy Jun 28 '13 at 14:35
  • Even iterators generally have identical performance between pre- and post-increment, since they are usually just wrapped pointers. Still, you are right that using pre-increment when possible might gain you some performance, and almost certainly won't be worse. – zennehoy Jun 28 '13 at 14:39
  • @zennehoy I don't think I understand what you're first comment is supposed to mean, while you're confirming my answer in your second. – Tim Jun 28 '13 at 14:40
  • @zennehoy About the iterators, an iterator depends heavily on its containers implementation. Calling it a wrapped pointer is somewhat vague in my opinion. Besides pre-increment still returns an reference instead of an copy in the case of iterators. – Tim Jun 28 '13 at 14:47
  • I was just commenting on the fact that there is not _necessarily_ a difference in speed - neither for builtin types nor for class types. As for iterators, even though the implementation of the increment, decrement and other operators depends heavily on the container, pretty much all iterators have a sizeof equal to that of a pointer (std::vector::iterator is one rare exception). – zennehoy Jun 28 '13 at 15:10
  • @zennehoy See the linked question for disapproval for your statements above. If it is being optimized, I think that's where you're after, then it is nothing more or less then calling a pre-increment operator, if a class follows the usual design. Besides iterators are not always holding a single pointer, take a look at a linked list iterator. – Tim Jun 28 '13 at 16:01
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/32595/discussion-between-zennehoy-and-tim) – zennehoy Jun 28 '13 at 19:40
  • The brevity of this answer shouldn't be a discount on its validity. The first statement is *exactly* what happens, and a surprisingly large number of engineer are oblivious to that fact. Given `j = i++;` they assume the increment always takes place after the assignment, when in reality it is pinned to the eval of `i` ; the assignment is literally an aftert-thing. – WhozCraig Jun 01 '20 at 04:46
24

Basic answer for understanding. The incrementation operator works like this:

// ++i
function pre_increment(i) {
    i += 1;
    return i;
}
// i++
function post_increment(i) {
    copy = i;
    i += 1;
    return copy;
}

A good compiler will automatically replace i++ with ++i when it detect that the returned value will not be used.

Kulvar
  • 1,139
  • 9
  • 22
6

In pre-increment the initial value is first incremented and then used inside the expression.

a = ++i;

In this example suppose the value of variable i is 5. Then value of variable a will be 6 because the value of i gets modified before using it in a expression.

In post-increment value is first used in a expression and then incremented.

a = i++;

In this example suppose the value of variable i is 5. Then value of variable a will be 5 because value of i gets incremented only after assigning the value 5 to a .

Andreas
  • 5,393
  • 9
  • 44
  • 53
Pbk1303
  • 3,702
  • 2
  • 32
  • 47
5
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argp)
{
    int x = 5;

    printf("x=%d\n", ++x);
    printf("x=%d\n", x++);
    printf("x=%d\n", x);

    return EXIT_SUCCESS;
}

Program Output:

x=6
x=6
x=7

In the first printf statement x is incremented before being passed to printf so the value 6 is output, in the second x is passed to printf (so 6 is output) and then incremented and the 3rd printf statement just shows that post increment following the previous statement by outputting x again which now has the value 7.

Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88
Taha
  • 51
  • 1
  • 1
2

i++ uses i's value then increments it but ++i increments i's value before using it.

0

The difference between post- and pre-increment is really, in many cases subtle. post incremenet, aka num++, first creates a copy of num, returns it, and after that, increments it. Pre-increment, on the other hand, aka ++num, first evaluates, then returns the value. Most modern compilers, when seeing this in a loop, will generally optimize, mostly when post increment is used, and the returned initial value is not used. The most major difference between the 2 increments, where it is really common to make subtle bugs, is when declaring variables, with incremented values: Example below:

int num = 5;
int num2 = ++num; //Here, first num is incremented, 
                  //then made 6, and that value is stored in num2;

Another example:

int num = 5;
int num2 = num++; //Here, num is first returned, (unfortunately?), and then 
                  //incremented. This is useful for some cases.

The last thing here I want to say is BE CAREFUL WITH INCREMENTS. When declaring variables, make sure you use the right increment, or just write the whole thing out (num2 = num + 1, which doesn't always work, and is the equivalent of pre-increment). A lot of trouble will be saved, if you use the right increment.

Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88
0

it does not matter if you use pre or post increment in an independent statement, except for the pre-increment the effect is immediate

//an example will make it more clear:


int n=1;
printf("%d",n);
printf("%d",++n);// try changing it to n++(you'll get to know what's going on)

n++;
printf("%d",n);

output: 123