Iterating on a for loop with ++i or i++?

I see a lot of for loops around. and sometimes they are written like for(int i = 0; i < 10; i++) and sometimes they are written like for(int i = 0; i < 10; ++i).

And for some reason, they were different in my mind. For some reason, I thought ++i would increment at the beginning of the loop whereas i++ would increment at the end, but upon closer inspection, the code behavior didn’t reflect the assumptions I had. So why not do some investigation?

You may ask: “How do you investigate the differences?” And the answer for that is Assembly! Everything has to be translated to assembly at some point, so comparing assemblies will show you the real difference between implementations.

Consider the following code:

for(int i = 0; i < 10; i++) { }

Using godbolt we can take a look at how this is translated to assembly.

MyFunction():
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-4], 0
    jmp     .L2
.L3:
    add     DWORD PTR [rbp-4], 1
.L2:
    cmp     DWORD PTR [rbp-4], 9
    jle     .L3

In a few words, here’s what’s happening:

Well, I just described what a loop is, but let’s keep going.

What happens when I change i++ to ++i?

MyFunction():
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-4], 0
    jmp     .L2
.L3:
    add     DWORD PTR [rbp-4], 1
.L2:
    cmp     DWORD PTR [rbp-4], 9
    jle     .L3

Literally nothing!

So that was very anti-climatic and a very complicated way to say that there is no difference at all between those two things.

But hang on! What if we achieve this same behaviour with a while loop? Like so:

int i;
while(i < 10) {
    i++;
}

We obtain the following assembly for the above code:

MyFunction():
    push    rbp
    mov     rbp, rsp
    jmp     .L2
.L3:
    add     DWORD PTR [rbp-4], 1
.L2:
    cmp     DWORD PTR [rbp-4], 9
    jle     .L3
    nop

It’s the same! Were you expecting something different?