Skip to main content
GameDev.net gamedev.net
🔒 Locked

i++ vs ++i

Started by adam17 Aug 5, 2005 at 7:53 PM 39 replies 16k views
Original Post
adam17
adam17
whats the difference between i++ and ++i? i see it used alot in loops. what is the advantage of either method?
Max_Payne
Max_Payne
++i is pre-incrementation, and i++ is post-incrementation. They basically mean, increment before the value is evaluated, or increment after the value is evaluated, respectively.

If you did:

int i = 1;
std::cout << ++i; // <-- This outputs 2
std::cout << i; // <-- This outputs 2

But if you did:

int i = 1;
std::cout << i++; // <-- This outputs 1
std::cout << i; // <-- This outputs 2

Generally, its more efficient to do ++i, because i++ requires storing an intermediate value, incrementing, and then returning. For good practice, you should do ++i whenever you can, unless your real intended meaning is i++. However, modern compilers will do optimizations that will filter-out useless i++ statements and turn them into the equivalent of ++i.

In the case of loops, more specifically for loops, it makes no difference, because the incrementation is always done after each cycle of the loop. So whether you post-increment or pre-increment. Its done at the same time and the variable takes on the same value.

Looking for a serious game project?
www.xgameproject.com
SiCrane
SiCrane
i++ increments the value and returns the old value. ++i increments the value and returns the new value. For integers there is generally no performance difference, for more complex classes that implement operator++(), such as many iterators, generally you should use the ++i form unless you need the old value.
makeshiftwings
makeshiftwings
Quote:
Original post by Max_Payne
++i is pre-incrementation, while i++ is post-incrementation. They basically mean, increment before the value is evaluated, or increment after the value is evaluated, respectively.


To put it in more simple terms:

i = 3;x = i++;  //x is equal to 3, but i is now 4.j = 3;y = ++i;  //both y and j are equal to 4.
pinacolada
pinacolada
If you can go either way, my vote goes to i++ because the gain in readability far outweights the infinitesimal gain in performance.

But SiCrane's note about ++i for iterators is good.
adam17
adam17
that was quick! thanks alot for clearing that up for me.

damn i love this forum
Xai
Xai
The part no one has mentioned is this ... the most common use of i++ is in situations like this:

for(int i = 0; i < length; i++)

this is just plain silly. when executed as a full stament (not inside a bigger expression or statement), the results of pre and post increment are identical ... the value gets incremented by the end of the stament ... but the theory of the i++ version says that an intermediate is created to return the old value. While it is totally true that this gets optimized away for all integral types on all modern compilers ... it DOES NOT get optimized away if i is a custom class ...

for if you have a template written like this

template
void DoSomething(IteratorType begin, IteratorType end)
{
while(begin != end)
{
// Do Something Here

begin++; // this is just bad, it should be ++begin
}
}

// all three of these are for incrementing i
i = i + 1;
i += 1;
++i;

// this is for post incrementing i, ONLY used for cases where you need to cacluate based on the OLD value of i
i++
tgraupmann
tgraupmann
++i; is supposed to give you a small speed improvement.
*News tagenigma.com is my new domain.
Nypyren
Nypyren
If you don't use the intermediate value of 'var++', the compiler removes all the unnecessary code... even in the case of complex stuff like iterators.

This assumes you have a 'good' optimizer.

Yes, compilers ARE this smart. Assembly-level dependency graphing is freaking awesome.

Just remember, when you're looking at assembly, if you're using a debug build, you're probably not seeing optimized results.
MaulingMonkey
MaulingMonkey
Quote:
Original post by tgraupmann
++i; is supposed to give you a small speed improvement.


When i is an iterator, i++ may be slower than ++i. Key words: iterator, may. It should provide no noticable difference when i is an integer, nor is it guaranteed to be faster even when i is an iterator (although it should not be slower).

As such, it is good to get in the habit of writing the increment of loops as ++i rather than i++:

for ( ... ; ... ; ++i )
rather than:
for ( ... ; ... ; i++ )
(the two statements are equivilant otherwise)

However, do not avoid i++ on the basis that "it will be slower" when it will make your code clearer.
Thevenin
Thevenin
Quote:
Original post by makeshiftwings
To put it in more simple terms:

i = 3;x = i++;  //x is equal to 3, but i is now 4.j = 3;y = ++i;  //both y and j are equal to 4.


Uhm.. unless j is a mispelling for i, than I've seriously overlooked those operators all these years... [rolleyes]
Inmate2993
Inmate2993
i++; and ++i; both get optomized by most modern C compilers to be the same.

Personally though, i+=1; is more readable and its optomized to be the same as i++; and ++i; so this is all academic.
william bubel
iMalc
iMalc
Quote:
Original post by Nypyren
If you don't use the intermediate value of 'var++', the compiler removes all the unnecessary code... even in the case of complex stuff like iterators.

This assumes you have a 'good' optimizer.
The reality is that there are a lot of different compilers out there and for many of them there will be a speed difference between the two for non built-in data types.

I personally don't think there is a readability difference. It's just about preferring the one you use the most, or learnt first.
I could argue that they should be read aloud as:
i = i + 1; // i "is assigned" i "plus" 1i += 1;    // i "is incremented by" 1i++;       // i "is incremented"++i;       // "increment" i
So ++i wins in read(aloud)ability?
Or perhaps I'm just messing with ya! [grin]
CJH
CJH
Man, what is it with the 'increment' issue? Singletons too.
cignox1
cignox1
As suggested before, use ++i whenever you can. In my raytracer I got a 0.1s improvement in a 1.6s rendering just by replacing all the i++ to ++i (expecially for STL classes with iterators).
Nitage
Nitage
Quote:
Original post by Nypyren
If you don't use the intermediate value of 'var++', the compiler removes all the unnecessary code... even in the case of complex stuff like iterators.

This assumes you have a 'good' optimizer.

Yes, compilers ARE this smart. Assembly-level dependency graphing is freaking awesome.

Just remember, when you're looking at assembly, if you're using a debug build, you're probably not seeing optimized results.


operator++(int) and operator++() could be overloaded to do totally different things, so a compiler cannot optimize this away in all cases.

Additionally, when I see i++ in a loop, I assume that whoever wrote the loop doesn't know the difference between i++ and ++i. If I was gicing a technical interview abd the candidate wrote i++ instead of ++i, I'd think very slightly less of the programmer (if he'd claimed to be a C++ expert).


I also don't think that use post-increment makes code clearer - if anything it make code less readable.
Inmate2993
Inmate2993
int main(int argc, char ** argv){  int i = 0;  i++;  ++i;  i += 1;  i = i + 1;  return 0;}


gcc version 3.2.3 (mingw special 20030504-1)

	.file	"testinc.c"	.def	___main;	.scl	2;	.type	32;	.endef	.text.globl _main	.def	_main;	.scl	2;	.type	32;	.endef_main:	pushl	%ebp	movl	%esp, %ebp	subl	$8, %esp	andl	$-16, %esp	movl	$0, %eax	movl	%eax, -8(%ebp)	movl	-8(%ebp), %eax	call	__alloca	call	___main	movl	$0, -4(%ebp)	leal	-4(%ebp), %eax	incl	(%eax)	leal	-4(%ebp), %eax	incl	(%eax)	leal	-4(%ebp), %eax	incl	(%eax)	leal	-4(%ebp), %eax	incl	(%eax)	movl	$0, %eax	leave	ret


I'll draw your attention to the 4 blocks of code that look like so:
	leal	-4(%ebp), %eax	incl	(%eax)


All 4 types of increment on gcc compilers are equivalent. Any technical interviewer that thought less of me because I used one over the other, I'll tell him to shove that job right up his ass.
william bubel
load_bitmap_file
load_bitmap_file
Quote:
Original post by Inmate2993
*** Source Snippet Removed ***

gcc version 3.2.3 (mingw special 20030504-1)

	.file	"testinc.c"	.def	___main;	.scl	2;	.type	32;	.endef	.text.globl _main	.def	_main;	.scl	2;	.type	32;	.endef_main:	pushl	%ebp	movl	%esp, %ebp	subl	$8, %esp	andl	$-16, %esp	movl	$0, %eax	movl	%eax, -8(%ebp)	movl	-8(%ebp), %eax	call	__alloca	call	___main	movl	$0, -4(%ebp)	leal	-4(%ebp), %eax	incl	(%eax)	leal	-4(%ebp), %eax	incl	(%eax)	leal	-4(%ebp), %eax	incl	(%eax)	leal	-4(%ebp), %eax	incl	(%eax)	movl	$0, %eax	leave	ret


I'll draw your attention to the 4 blocks of code that look like so:
	leal	-4(%ebp), %eax	incl	(%eax)


All 4 types of increment on gcc compilers are equivalent. Any technical interviewer that thought less of me because I used one over the other, I'll tell him to shove that job right up his ass.


But that's only for ints. It'd be more interesting to see what happens with something more complex like say, an iterator.
pi_equals_3
pi_equals_3
Quote:
Original post by Inmate2993
Any technical interviewer that thought less of me because I used one over the other, I'll tell him to shove that job right up his ass.


Exactly. In every professional situation I've been in so far, everyone I've worked with has preferred i++ over ++i. That doesn't mean that they don't know the difference.

Now, if I interviewed someone who didn't know why they were different at all, that's another story.

Edit: Of course, in most cases I can imagine, I would rather have a programmer who knew how to program well over a programmer who knew everything about a certain language.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.