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.