| Topic: |
DEVELOP > c-Plus-Plus |
| User: |
"" |
| Date: |
24 Jan 2008 11:24:49 PM |
| Object: |
basic for loop question |
Is there any difference between
for(int i = 0; some condition; i++)
{....}
and
for(int i = 0; some condition; ++i) ?
{....}
It seems not, by some experimenting, but I thought it was worth
checking since j++ and ++j usually mean different things in the
language ++c .
Thanks a lot,
Paul Epstein
.
|
|
| User: "Alf P. Steinbach" |
|
| Title: Re: basic for loop question |
24 Jan 2008 11:35:48 PM |
|
|
* pauldepstein@att.net:
Is there any difference between
for(int i = 0; some condition; i++)
{....}
and
for(int i = 0; some condition; ++i) ?
{....}
Technically no.
For forming habit of writing only what you mean, not requesting
additional needless operations (i.e. formong the habit of writing ++i
instead of i++), yes there is a difference.
This difference can be important when "i" is not a simple integer,
because i++ then generally has to make a copy.
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.
|
|
|
|
| User: "Mateusz Loskot" |
|
| Title: Re: basic for loop question |
24 Jan 2008 11:59:38 PM |
|
|
wrote:
Is there any difference between
for(int i = 0; some condition; i++)
{....}
and
for(int i = 0; some condition; ++i) ?
{....}
It seems not, by some experimenting, but I thought it was worth
checking since j++ and ++j usually mean different things in the
language ++c .
You mean difference in...performance, semantic,...?
Semantically, there is a difference because in the first case
temporary object is created.
There may or may not be difference in speed and performance. it depends
on C++ implementation you use, optimization, etc.
Cheers
--
Mateusz Loskot
http://mateusz.loskot.net
.
|
|
|
| User: "" |
|
| Title: Re: basic for loop question |
25 Jan 2008 04:40:43 AM |
|
|
On 25 Jan, 05:59, Mateusz Loskot <see...@signature.net> wrote:
pauldepst...@att.net wrote:
Is there any difference between
for(int i = 0; some condition; i++)
{....}
and
for(int i = 0; some condition; ++i) ?
{....}
It seems not, by some experimenting, but I thought it was worth
checking since j++ and ++j usually mean different things in the
language ++c .
You mean difference in...performance, semantic,...?
Semantically, there is a difference because in the first case
temporary object is created.
There may or may not be difference in speed and performance. it depends
on C++ implementation you use, optimization, etc.
Generally speaking (and the FAQ book from Cline et al concurs:
Q23.08), one should use the prefix increment if the previous value of
the operand is discarded, as in the example above. The rationale is
that the postfix operator needs to make a copy of the operand,
increment the operand, then return the value of the copy; the prefix
operator merely needs to increment the operand and return its value.
.
|
|
|
| User: "Lionel B" |
|
| Title: Re: basic for loop question |
25 Jan 2008 05:05:35 AM |
|
|
On Fri, 25 Jan 2008 02:40:43 -0800, keith wrote:
On 25 Jan, 05:59, Mateusz Loskot <see...@signature.net> wrote:
pauldepst...@att.net wrote:
Is there any difference between
for(int i = 0; some condition; i++)
{....}
and
for(int i = 0; some condition; ++i) ? {....}
It seems not, by some experimenting, but I thought it was worth
checking since j++ and ++j usually mean different things in the
language ++c .
You mean difference in...performance, semantic,...?
Semantically, there is a difference because in the first case temporary
object is created.
There may or may not be difference in speed and performance. it depends
on C++ implementation you use, optimization, etc.
Generally speaking (and the FAQ book from Cline et al concurs: Q23.08),
one should use the prefix increment if the previous value of the operand
is discarded, as in the example above. The rationale is that the
postfix operator needs to make a copy of the operand, increment the
operand, then return the value of the copy; the prefix operator merely
needs to increment the operand and return its value.
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to generate
identical code here), but when incrementing an object with a non-trivial
copy constructor it potentially could make a difference.
--
Lionel B
.
|
|
|
| User: "Joe Greer" |
|
| Title: Re: basic for loop question |
25 Jan 2008 07:08:22 AM |
|
|
Lionel B <me@privacy.net> wrote in news:fncfpv$ebq$2@south.jnrs.ja.net:
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to generate
identical code here), but when incrementing an object with a non-trivial
copy constructor it potentially could make a difference.
The way I look at it is that ++i and i++ take the same number of keystrokes
to type and ++i better indicates what I mean (increment i and use that
value). That it has the side benefit of being more efficient without
relying on QOI is just a side benefit. In the case of user defined objects
with overloaded operator++, I am not sure how you could do it without
making a copy, but even if you could I don't think I would like to rely on
QOI to make that decision.
joe
.
|
|
|
| User: "Rolf Magnus" |
|
| Title: Re: basic for loop question |
26 Jan 2008 11:11:03 AM |
|
|
Joe Greer wrote:
Lionel B <me@privacy.net> wrote in news:fncfpv$ebq$2@south.jnrs.ja.net:
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to generate
identical code here), but when incrementing an object with a non-trivial
copy constructor it potentially could make a difference.
The way I look at it is that ++i and i++ take the same number of
keystrokes to type and ++i better indicates what I mean (increment i and
use that value).
You don't use the value (at least not in the example the OP posted). You
discard it. So in that regard, both variants are the same. With ++i, you
discard the new value, with i++, you discard the old one.
.
|
|
|
|
| User: "Lionel B" |
|
| Title: Re: basic for loop question |
25 Jan 2008 10:27:39 AM |
|
|
On Fri, 25 Jan 2008 14:08:22 +0100, Joe Greer wrote:
Lionel B <me@privacy.net> wrote in news:fncfpv$ebq$2@south.jnrs.ja.net:
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to
generate identical code here), but when incrementing an object with a
non-trivial copy constructor it potentially could make a difference.
The way I look at it is that ++i and i++ take the same number of
keystrokes to type and ++i better indicates what I mean (increment i and
use that value).
I don't dispute that. I use prefix incrementation myself for simple loop
counters, or generally when the semantics doesn't require postfix
incrementation. However, that was not the point of my post.
That it has the side benefit of being more efficient
I imagine it would be equally efficient with basic optimisation... *if*
the compiler is allowed *not* to copy the object when it can establish
that the return value is not used.
without relying on QOI is just a side benefit.
I'm sorry, I have no idea what QOI means.
In the case of user
defined objects with overloaded operator++, I am not sure how you could
do it without making a copy,
Nor do I, but again, my query was kind of the converse of that: if you
use postfix increment in a situation where, say, you don't use the return
value, then can you make any assumptions about whether copying takes
place or not? (I guess the answer is probably "no you may not"...).
--
Lionel B
.
|
|
|
| User: "Joe Greer" |
|
| Title: Re: basic for loop question |
25 Jan 2008 11:26:53 AM |
|
|
Lionel B <me@privacy.net> wrote in news:fnd2lr$ebq$3@south.jnrs.ja.net:
I'm sorry, I have no idea what QOI means.
Sorry, that would be quality of implementation. In other words, just
because an implementation can make an optimization, doesn't mean it will.
In the case of user
defined objects with overloaded operator++, I am not sure how you
could do it without making a copy,
Nor do I, but again, my query was kind of the converse of that: if you
use postfix increment in a situation where, say, you don't use the
return value, then can you make any assumptions about whether copying
takes place or not? (I guess the answer is probably "no you may
not"...).
Yep, you can't really make any assumptions about it.
joe
.
|
|
|
|
| User: "=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=" |
|
| Title: Re: basic for loop question |
25 Jan 2008 12:52:04 PM |
|
|
On 2008-01-25 17:27, Lionel B wrote:
On Fri, 25 Jan 2008 14:08:22 +0100, Joe Greer wrote:
Lionel B <me@privacy.net> wrote in news:fncfpv$ebq$2@south.jnrs.ja.net:
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to
generate identical code here), but when incrementing an object with a
non-trivial copy constructor it potentially could make a difference.
The way I look at it is that ++i and i++ take the same number of
keystrokes to type and ++i better indicates what I mean (increment i and
use that value).
I don't dispute that. I use prefix incrementation myself for simple loop
counters, or generally when the semantics doesn't require postfix
incrementation. However, that was not the point of my post.
That it has the side benefit of being more efficient
I imagine it would be equally efficient with basic optimisation... *if*
the compiler is allowed *not* to copy the object when it can establish
that the return value is not used.
And provided that it is as simple as just neglecting to create a copy,
not that I can come up with an example but one could imagine that there
were some other complications which makes it difficult for the compiler
to skip the part of the code which creates the copy.
without relying on QOI is just a side benefit.
I'm sorry, I have no idea what QOI means.
Quality Of Implementation.
In the case of user
defined objects with overloaded operator++, I am not sure how you could
do it without making a copy,
Nor do I, but again, my query was kind of the converse of that: if you
use postfix increment in a situation where, say, you don't use the return
value, then can you make any assumptions about whether copying takes
place or not? (I guess the answer is probably "no you may not"...).
Generally you can not make such an assumption, no. With a good compiler
and with no weird implementations of the ++ operator you might, but
unless you check the code generated for each usage you can never be sure.
--
Erik Wikström
.
|
|
|
| User: "James Kanze" |
|
| Title: Re: basic for loop question |
25 Jan 2008 01:41:18 PM |
|
|
On Jan 25, 7:52 pm, Erik Wikstr=F6m <Erik-wikst...@telia.com> wrote:
On 2008-01-25 17:27, Lionel B wrote:
In the case of user defined objects with overloaded
operator++, I am not sure how you could do it without
making a copy,
Nor do I, but again, my query was kind of the converse of that: if you
use postfix increment in a situation where, say, you don't use the retur=
n
value, then can you make any assumptions about whether copying takes
place or not? (I guess the answer is probably "no you may not"...).
Generally you can not make such an assumption, no. With a good
compiler and with no weird implementations of the ++ operator
you might, but unless you check the code generated for each
usage you can never be sure.
Use the copy in any way. Use the copy in the postfix increment
operator, for example, something like:
T
operator++( T& obj, int )
{
T result( obj ) ;
operator++( obj ) ;
result.dump( std::cout ) ; // outputs internal state...
return result ;
}
It's easy to invent cases where postfix would be slower. The
fact is that they don't occur in practice. To begin with, the
copy must be fast and efficient to begin with, since the STL
copies iterators like crazy anyway. And the things you do to
make it fast and efficient (e.g. like keeping the internal state
simple, and making the copy constructor inline) help the
compiler in optimizing it.
I've posted this several times before, but I carefully
benchmarked loops with prefix and postfix increment, for all of
the standard iterators, using g++, and there was no difference.
One thing that did make a difference (although not a large one)
was moving the call to end() out of the loop:
for ( Iter i =3D c.begin(), e =3D c.end() ; i !=3D e ; i ++ ) {
}
turns out to be measurably faster than:
for ( Iter i =3D c.begin() ; i !=3D c.end() ; ++ i ) {
}
in fact. But the difference is always small enough that it
would be foolish and a waste of time to even think about it
(until the profiler says otherwise, of course).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
|
|
|
|
|
|
|
| User: "" |
|
| Title: Re: basic for loop question |
25 Jan 2008 06:58:18 AM |
|
|
On 25 Jan, 11:05, Lionel B <m...@privacy.net> wrote:
On Fri, 25 Jan 2008 02:40:43 -0800, keith wrote:
Generally speaking (and the FAQ book from Cline et al concurs: Q23.08),
one should use the prefix increment if the previous value of the operand
is discarded, as in the example above. The rationale is that the
postfix operator needs to make a copy of the operand, increment the
operand, then return the value of the copy; the prefix operator merely
needs to increment the operand and return its value.
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to generate
identical code here), but when incrementing an object with a non-trivial
copy constructor it potentially could make a difference.
I doubt the standard has anything to say on the matter, but how else
would you increment the operand (whatever that might mean for the
object concerned), _and_then_ return the previous value?
.
|
|
|
| User: "Lionel B" |
|
| Title: Re: basic for loop question |
25 Jan 2008 10:30:15 AM |
|
|
On Fri, 25 Jan 2008 04:58:18 -0800, keith wrote:
On 25 Jan, 11:05, Lionel B <m...@privacy.net> wrote:
On Fri, 25 Jan 2008 02:40:43 -0800, keith wrote:
Generally speaking (and the FAQ book from Cline et al concurs:
Q23.08), one should use the prefix increment if the previous value of
the operand is discarded, as in the example above. The rationale is
that the postfix operator needs to make a copy of the operand,
increment the operand, then return the value of the copy; the prefix
operator merely needs to increment the operand and return its value.
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to
generate identical code here), but when incrementing an object with a
non-trivial copy constructor it potentially could make a difference.
I doubt the standard has anything to say on the matter, but how else
would you increment the operand (whatever that might mean for the object
concerned), _and_then_ return the previous value?
Sorry, I obviously didn't express myself very well... the situation I had
in mind is where the return value of postfix increment is *discarded*.
Then, is the compiler allowed *not* to make a copy of the object?
--
Lionel B
.
|
|
|
| User: "=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=" |
|
| Title: Re: basic for loop question |
25 Jan 2008 12:42:44 PM |
|
|
On 2008-01-25 17:30, Lionel B wrote:
On Fri, 25 Jan 2008 04:58:18 -0800, keith wrote:
On 25 Jan, 11:05, Lionel B <m...@privacy.net> wrote:
On Fri, 25 Jan 2008 02:40:43 -0800, keith wrote:
Generally speaking (and the FAQ book from Cline et al concurs:
Q23.08), one should use the prefix increment if the previous value of
the operand is discarded, as in the example above. The rationale is
that the postfix operator needs to make a copy of the operand,
increment the operand, then return the value of the copy; the prefix
operator merely needs to increment the operand and return its value.
Out of interest, does the standard mandate that the postfix version is
*required* to make a copy? Obviously it's not going to make any
difference for an int (and I'd expect an optimising compiler to
generate identical code here), but when incrementing an object with a
non-trivial copy constructor it potentially could make a difference.
I doubt the standard has anything to say on the matter, but how else
would you increment the operand (whatever that might mean for the object
concerned), _and_then_ return the previous value?
Sorry, I obviously didn't express myself very well... the situation I had
in mind is where the return value of postfix increment is *discarded*.
Then, is the compiler allowed *not* to make a copy of the object?
There is something called the "as if" rule (section 1.9 of the standard)
which basically says that as long as the observable behaviour of the
program during execution is the same as if things were done as described
in the standard then the program is conforming. So if you do not try to
make any use of the returned value then the compiler should be free to
do nothing except increment the value.
For an integer this should be simple but for user defined types the
compiler might have some trouble to decide how much of the code is
needed an what it can safely skip, which is why it is generally
recommended to use the prefix version.
--
Erik Wikström
.
|
|
|
|
|
|
|
|
|
| User: "James Kanze" |
|
| Title: Re: basic for loop question |
25 Jan 2008 07:21:25 AM |
|
|
On Jan 25, 6:24 am, wrote:
Is there any difference between
for(int i =3D 0; some condition; i++)
{....}
and
for(int i =3D 0; some condition; ++i) ?
{....}
Yes. One is what other people on the project are doing in
similar cases. The other is not.
It seems not, by some experimenting, but I thought it was
worth checking since j++ and ++j usually mean different things
in the language ++c .
The difference is in the returned value. In this case, the
returned value is being ignored.
There have been claims (and still are, by people who prefer
speculation to measurement) that the prefix version will be
faster for user defined types, like iterators. For this reason,
on a green fields project, it is probably simpler to choose
prefix notation, and avoid the arguments. If there is any
existing code, however, just use whatever it uses, and don't
worry about it.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
|
|
|
| User: "Rolf Magnus" |
|
| Title: Re: basic for loop question |
26 Jan 2008 11:15:15 AM |
|
|
James Kanze wrote:
On Jan 25, 6:24 am, wrote:
Is there any difference between
for(int i = 0; some condition; i++)
{....}
and
for(int i = 0; some condition; ++i) ?
{....}
Yes. One is what other people on the project are doing in
similar cases. The other is not.
It seems not, by some experimenting, but I thought it was
worth checking since j++ and ++j usually mean different things
in the language ++c .
The difference is in the returned value. In this case, the
returned value is being ignored.
There have been claims (and still are, by people who prefer
speculation to measurement) that the prefix version will be
faster for user defined types, like iterators. For this reason,
on a green fields project, it is probably simpler to choose
prefix notation, and avoid the arguments. If there is any
existing code, however, just use whatever it uses, and don't
worry about it.
Considering that - except for the potential difference in execution time -
there is no difference, why use the postfix version? If I definitely don't
gain anything from one solution, but might (even if chances are slim) gain
something from the other, then I use of course that one.
.
|
|
|
| User: "James Kanze" |
|
| Title: Re: basic for loop question |
27 Jan 2008 06:12:08 AM |
|
|
On Jan 26, 6:15 pm, Rolf Magnus <ramag...@t-online.de> wrote:
James Kanze wrote:
[...]
There have been claims (and still are, by people who prefer
speculation to measurement) that the prefix version will be
faster for user defined types, like iterators. For this reason,
on a green fields project, it is probably simpler to choose
prefix notation, and avoid the arguments. If there is any
existing code, however, just use whatever it uses, and don't
worry about it.
Considering that - except for the potential difference in
execution time - there is no difference, why use the postfix
version?
Typically, because it is the established coding convention where
you're working.
If I definitely don't gain anything from one solution, but
might (even if chances are slim) gain something from the
other, then I use of course that one.
Supposing all other things equal. They usually aren't. If your
shop has the established tradition of using the postfix op
(frequent, if for no other reason that that's what K&R did),
that's a very strong reason for using postfix---it requires (or
should require) significant motivation to change. And that
significant motivation isn't there.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
|
|
|
|
|
|

|
Related Articles |
|
|