difference between i++ and ++i in a for loop

S

ssylee

What's the difference between i++ and ++i in the following:

for (i = 0; i < maxNum; i++)
{
// what is i here at the first iteration?
}

for (i = 0; i < maxNum; ++i)
{
// what is i here at the first iteration?
}

I know this may be a stupid question, and may even be on the FAQ
already. But I don't exactly know the term of this observation. It
would be great if some advices could head to this message. Thanks.
 
A

Alf P. Steinbach

* ssylee:
What's the difference between i++ and ++i in the following:

for (i = 0; i < maxNum; i++)
{
// what is i here at the first iteration?
}

for (i = 0; i < maxNum; ++i)
{
// what is i here at the first iteration?
}

In this context there's no difference in the code's behavior.

The only difference is in the forming of coding habits.

Preferentially write '++i' unless really need 'i++' (which does a little more).


Cheers & hth.,

- Alf
 
M

Michael Mol

What's the difference between i++ and ++i in the following:

for (i = 0; i < maxNum; i++)
{
// what is i here at the first iteration?

}

for (i = 0; i < maxNum; ++i)
{
// what is i here at the first iteration?

}

I know this may be a stupid question, and may even be on the FAQ
already. But I don't exactly know the term of this observation. It
would be great if some advices could head to this message. Thanks.

For "++i", the ++ is called a preincrement. For "i++", the ++ is
called a postincrement.

As J. Shwab mentioned, ++i increments i directly. i++ returns a copy
of i, then increments it. But since "; i++)" doesn't do anything with
the statement's return, the copy is discarded. If the type of i is
non-trivial, the copy of the i++ may be expensive to produce, if
you're only going to discard it. Additionally, if the i type
overloads the postincrement ++ operator, you may get additional side-
effects, but situations are very rare. (As in, I've never seen it.)

IMHO, A good rule of thumb is "Always pre-increment unless you need to
save the old value."
 
J

James Kanze

What's the difference between i++ and ++i in the following:
for (i = 0; i < maxNum; i++)
{
// what is i here at the first iteration?
}
for (i = 0; i < maxNum; ++i)
{
// what is i here at the first iteration?
}
I know this may be a stupid question, and may even be on the
FAQ already. But I don't exactly know the term of this
observation. It would be great if some advices could head to
this message. Thanks.

The difference between i++ and ++i is in the value of the
result. In cases like the above, where the value of the result
is ignored, there is no difference.

Depending on the types involved, and how the compiler handles
them, there may be a difference in performance. At least,
people keep claiming this; I've done a lot of measurements, and
I've never been able to find any; I think it's one of those
myths that people like to perpetrate.
 
A

Alexander Gutenev

Depending on the types involved, and how the compiler handles
them, there may be a difference in performance. šAt least,
people keep claiming this; I've done a lot of measurements, and
I've never been able to find any; I think it's one of those
myths that people like to perpetrate.

For int there would not be any differene, but you can see the
diference on the code like:
for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i);
vs
for (std::set<int>::iterator i = s.begin(); i != s.end(); i++);
 
S

Sarath

What's the difference between i++ and ++i in the following:

for (i = 0; i < maxNum; i++)
{
// what is i here at the first iteration?

}

for (i = 0; i < maxNum; ++i)
{
// what is i here at the first iteration?

}

I know this may be a stupid question, and may even be on the FAQ
already. But I don't exactly know the term of this observation. It
would be great if some advices could head to this message. Thanks.

There's no big difference when you use it with primitive data types.
See the following declaration
class Myclass
{
int x;
public:
Myclass() : x(0)
{

}
Myclass& operator++()
{ // pre-increment
printf("pre-increment");
++x;
return *this;
}

Myclass operator++(int)
{
printf("post-increment");
// Make a copy current object
Myclass Temp = *this;
++*this; // calling pre-increment implementation
return Temp; // return temporary object
}
};


In this the above class post increment class returns the creates a
temporary objects to implement the post increment behavior (check C++
documentation). So unnecessarily using post increment operation costs
the creation of a temporary objects.
In the case of for loops, use pre-increment operators especially when
you use iterators.
 
R

Rolf Magnus

James said:
The difference between i++ and ++i is in the value of the
result. In cases like the above, where the value of the result
is ignored, there is no difference.

Depending on the types involved, and how the compiler handles
them, there may be a difference in performance. At least,
people keep claiming this; I've done a lot of measurements, and
I've never been able to find any; I think it's one of those
myths that people like to perpetrate.

Well, as long as you don't use the result, there is no disadvantage when
prefering ++i over i++, and even only a slight chance at improving
performance a little outweighs no advantage at all.
 
J

James Kanze

For int there would not be any differene, but you can see the
diference on the code like:
for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i);
vs
for (std::set<int>::iterator i = s.begin(); i != s.end(); i++);

I didn't see it when I measured. I measured *all* of the
iterators in the standard library (using the g++
implementations), and found no difference for any of them.
 
J

James Kanze

Well, as long as you don't use the result, there is no
disadvantage when prefering ++i over i++,

When you've already got a couple of a million lines of code
which systematically uses i++, there is. On a green fields
project, where you're creating a new coding guidelines, I'd go
with ++i, if for no other reason that it shuts up people who've
read an article somewhere, but have nver bothered to measure.
But it's certainly not worth changing an existing coding
guideline, or modifying existing code. Or being inconsistent.
and even only a slight chance at improving performance a
little outweighs no advantage at all.

Being consistent is an advantage. Not having to modify existing
code is an advantage.
 
J

James Kanze

There's no big difference when you use it with primitive data
types. See the following declaration
class Myclass
{
int x;
public:
Myclass() : x(0)
{

}
Myclass& operator++()
{ // pre-increment
printf("pre-increment");
++x;
return *this;
}

Myclass operator++(int)
{
printf("post-increment");
// Make a copy current object
Myclass Temp = *this;
++*this; // calling pre-increment implementation
return Temp; // return temporary object
}

};
In this the above class post increment class returns the
creates a temporary objects to implement the post increment
behavior (check C++ documentation). So unnecessarily using
post increment operation costs the creation of a temporary
objects.

Except that the compiler can easily see that the object isn't
used, and suppress it. I've measured this a number of times,
and it just doesn't make a difference. (Curiously enough,
calling end() each time in the loop does. Compilers don't seem
to be able to recognize that it is an invariant, and hoist the
call out of the loop, even when end() is inline.)
 
R

Rolf Magnus

James said:
When you've already got a couple of a million lines of code
which systematically uses i++, there is.
Agreed.

On a green fields project, where you're creating a new coding guidelines,
I'd go with ++i, if for no other reason that it shuts up people who've
read an article somewhere, but have nver bothered to measure.

Why should they bother? That's my point. Just use ++i, and if it's not
faster that way, you have lost nothing.
But it's certainly not worth changing an existing coding
guideline, or modifying existing code. Or being inconsistent.

Your coding guideline forces you to use postfix operator ++?
 
J

James Kanze

Your coding guideline forces you to use postfix operator ++?

It depends. A good coding guideline will say one way or the
other. And if it was originally written some time ago, there's
a good chance that it will say postfix---for various historical
reasons, that was what was most widespread in the past.
 
R

Rolf Magnus

James said:
Except that the compiler can easily see that the object isn't
used, and suppress it. I've measured this a number of times,
and it just doesn't make a difference. (Curiously enough,
calling end() each time in the loop does. Compilers don't seem
to be able to recognize that it is an invariant, and hoist the
call out of the loop, even when end() is inline.)

What do you mean by "Compilers" here? How many did you try?
 
S

SG

Being consistent is an advantage.  Not having to modify existing
code is an advantage.

I agree with Noah Roberts and Rolf Magnus on this. A coding guideline
that forces me to write "i++" when all i need is "++i" is a sign of
overregulation.

I also like to mention that things like "++i" hardly qualify as
premature optimization. I don't need to make measurements for writing
"++i" instead of "i++" even if the compiler is smart enough to
generate the same assembly (at least for built-in types).

Cheers!
SG
 
J

Juha Nieminen

James said:
Depending on the types involved, and how the compiler handles
them, there may be a difference in performance. At least,
people keep claiming this; I've done a lot of measurements, and
I've never been able to find any; I think it's one of those
myths that people like to perpetrate.

I think that, in the end, it's a question of how smart your compiler
is at optimizing.

It's quite clear that, for example, for iterators the postfix
increment operator is more complicated than the prefix one.

If you use the postfix increment on an iterator and don't use the
result, then it's up to the compiler to see this typical pattern and
optimize the code to be equivalent to the prefix increment version.

Are all compilers able to do this? I don't know. But why take the
risk, given that using the prefix ++ is in no way more laborious than
using the postfix one.
 
N

Noah Roberts

SG said:
I agree with Noah Roberts and Rolf Magnus on this. A coding guideline
that forces me to write "i++" when all i need is "++i" is a sign of
overregulation.

I also like to mention that things like "++i" hardly qualify as
premature optimization. I don't need to make measurements for writing
"++i" instead of "i++" even if the compiler is smart enough to
generate the same assembly (at least for built-in types).

And this is something you cannot assume. Therefore your measurements
may be invalid. The reason being that a change of compiler (which we
always end up doing even if just to upgrade) can change the
optimizations performed by the compiler. This is one of those times
when you can see that, short of standard compliant but standard
unspecified optimizations, one version of the code is going to have
intrinsically more steps than the other.

Performing an operation in less steps is actually an algorithmic
improvement, which is actually the correct way to optimize.

This isn't something to put in a coding standard though. This is just
common sense stuff that everyone should be doing anyway. A standard
that is too thick is not possible to memorize, track, enforce, or
adequately follow without huge expense.
 
J

James Kanze

What do you mean by "Compilers" here? How many did you try?

You got me there. I only did the measurements once, using g++
(and I forget which version). To tell the truth, I'd naively
expected some differences (albeit small differences) between
prefix and postfix for the more complicated iterators, and
didn't really expect it for manually hoisting the call to end()
(an inline function in most, if not all containers) out of the
loop. Where as I got exactly 0 difference between prefix and
postfix, for all iterators, but a fairly important difference
(but still only relevant for a very trivial loop in a critical
path) for hoising end() out of the loop.

My conclusion is simple: if you're dealing with an existing code
base which uses exclusively prefix or postfix (whether because
it is required by the coding standard, or simply because that's
the way it was written), do what ever it does (unless, of
course, the profiler shows that you need to change it). And
even for hoisting end() out of the loop, I'd say don't bother
until the profiler says you have to.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,162
Messages
2,570,896
Members
47,434
Latest member
TobiasLoan

Latest Threads

Top