There is a well known C++ BKM for preferring pre-increment (++i) over post-increment (i++). The rationale is that when post-incrementing and object, the object must increment itself and then return a temporary containing its old value. While this makes perfect sense for complex types (e.g. STL iterators) I’ve always wondered if it holds true for built-in types such as int. Let’s find out.
First let’s create a trivial example to examine:
#include <iostream>
using namespace std;
int main()
{
// post-imcrement
for(int i=0; i<10; i++)
{
cout << "[" << i << "]" << endl;
}
// pre-imcrement
for(int i=0; i<10; ++i)
{
cout << "[" << i << "]" << endl;
}
return 0;
}
Now using the Visual Studio 2008 C++ compiler, let’s take a look at the generated assembly code. First let’s keep things simple and disable compiler optimizations (/Od):
// post-imcrement
for(int i=0; i<10; i++)
004114D3 mov dword ptr [i],0
004114D5 jmp main+30h (4114E0h)
004114D7 mov eax,dword ptr [i]
004114DA add eax,1
004114DD mov dword ptr [i],eax
004114E0 cmp dword ptr [i],0Ah
004114E4 jge main+86h (411536h)
{
<... snip ...>
// pre-imcrement
for(int i=0; i<10; ++i)
00411536 mov dword ptr [i],0
0041153D jmp main+98h (411548h)
0041153F mov eax,dword ptr [i]
00411542 add eax,1
00411545 mov dword ptr [i],eax
00411548 cmp dword ptr [i],0Ah
0041154C jge main+0EEh (41159Eh)
{
The relevant parts of the assembly code are highlighted. As you can see, there is no difference between the generated code for post-increment and pre-increment.
Now, with compiler optimizations enabled (\O2) and the relevant parts highlighted:
// post-imcrement
for(int i=0; i<10; i++)
00401008 xor esi,esi
0040100A lea ebx,[ebx]
{
<... snip ...>
0040104A inc esi
0040104B cmp esi,0Ah
0040104E jl main+10h (401010h)
}
// pre-imcrement
for(int i=0; i<10; ++i)
00401050 xor esi,esi
{
<... snip ...>
0040108C inc esi
0040108D cmp esi,0Ah
00401090 jl main+52h (401052h)
}
Again there is no difference in the generated assembly between post-increment and pre-increment.
So, based on this quick experiment, there is no difference between pre-increment and post-increment for int types when using the Visual Studio 2008 C++ compiler with optimizations enabled or disabled.
Note that this doesn’t change the BKM to prefer pre-increments over post-increments when using integer types. The above experiment was only conducted with a single compiler – other compilers may behave differently and so it is best to err on the side of caution and use pre-increments where possible. Also, the use of pre-increment adds some future proofing – if the type of the variable being incremented changed to a more complex type then pre-increment then becomes the optimal choice.
Tweet This Post
Digg This Post
Reddit
Stumble This Post
Tags: C++
The best reason for always using pre-increment/decrement is the genericity of the code.
A certain algorithm may one day become a generic one, and the types passed into it may no longer be simple ints.
There isn’t any reason for these two to differ if you don’t use the result at all.
probably sealed the pre/post increment argument permanently. Or at least should have. The question now and then, and there’s a wide consensus that in regular uses (e.g. using integers to iterate in a loop) there’s no performance difference for ~3 decades now.
Huh?? some markup mix trashed my comment. Here goes again, with explicit URLs:
Andrew Koenig probably sealed the pre/post increment argument permanently: http://dobbscodetalk.com/index.php?option=com_myblog&show=Efficiency-versus-intent.html&Itemid=29 .
Or at least should have. The question still arises now and then, and there’s a wide consensus that in regular uses (e.g. using integers to iterate in a loop) there’s no performance difference for ~3 decades now: http://stackoverflow.com/questions/24886?tab=oldest#tab-top