+77  A: 

[Executive Summary: Use ++i if you don't have a specific reason to use i++.]

For C++, the answer is a bit more complicated.

If i is a simple type (not an instance of a C++ class) then the answer given for C holds, since the compiler is generating the code.

However, if i is an instance of a C++ class, then i++ and ++i are making calls to the operator++() function. Here's a standard pair of these functions:

const Foo& Foo::operator++() // called for ++i
{
    this->mydata += 1;
    return *this;
}

const Foo Foo::operator++(int)  // called for i++
{
    Foo tmp(*this);   //*** variable "tmp" cannot be optimized away by the compiler
    this->data += 1;
    return tmp;
}

Since the compiler isn't generating code, but just calling the operator++ function, there is no way to optimize away the tmp variable and its associated copy constructor. If the copy constructor is expensive then this can have a significant performance impact.

(thanks to Paul for inquiring about the difference between C and C++.)

~~ Mark Harrison ~~

Mark Harrison
What the compiler can avoid is the second copy to return tmp, by allocating tmp in the caller, through NRVO, as mentioned by another comment.
Blaisorblade
i++ is one processor instruction slower
Joe Philllips
Can't the compiler avoid this altogether if operator++ is inlined?
Eduard - Gabriel Munteanu
Yes if operator++ is inlined and tmp is never used it can be removed unless the tmp object's constructor or destructor has side effects.
Zan Lynx
Mark: "this->data" is in one sample and "this->mydata" in the other...can you fix that up?
John Zwinck
C++ behavior is not so different from C's. If you think in terms of memory or register assignements, what C++ shows is what C compiler has to do behind the scene. Also many C++ compilers will use operator++() if no operator++(int) is defined (and issue a warning).
kriss
A: 

Thank you very much for your answer! Always a pleasure to read your answers.

poulejapon
+17  A: 

Yes. There is.

C++ has the notion of operator overloading. The ++ operator may or may not be defined as a function. For primitive types (int, double, ...) the operators are built in, so the compiler will probably be able to optimize your code. But in the case of an object that defines the ++ operator things are different.

The operator++(int) function must create a copy. That is because postfix ++ is expected to return a different value than what it holds: it must hold its value in a temp variable, increment its value and return the temp. In the case of operator++(), prefix ++, there is no need to create a copy: the object can increment itself and then simply return itself.

Here is an illustration of the point:

class C {
    int i_;
    int j_;
public:
    int operator++();    // prefix
    int operator++(int); // postfix
};

C C::operator++(int)
{
    C t(*this);
    ++(*this);
    return t; // return a copy
}

C& C::operator++()
{
    ++i_;
    ++j_;
    return *this; // self, no copy created
}

Every time you call operator++(int) you must create a copy, and the compiler can't do anything about it. When given the choice, use operator++(); this way you save a copy. It might be significant in the case of many increments (large loop?) and/or large objects.

wilhelmtell
+11  A: 

It's not entirely correct to say that the compiler can't optimize away the temporary variable copy in the postfix case. A quick test with VC shows that it, at least, can do that in certain cases.

In the following example, the code generated is identical for prefix and postfix, for instance:

#include <stdio.h>

class Foo
{
public:

 Foo() { myData=0; }
 Foo(const Foo &rhs) { myData=rhs.myData; }

 const Foo& operator++()
 {
  this->myData++;
  return *this;
 }

 const Foo operator++(int)
 {
  Foo tmp(*this);
  this->myData++;
  return tmp;
 }

 int GetData() { return myData; }

private:

 int myData;
};

int main(int argc, char* argv[])
{
 Foo testFoo;

 int count;
 printf("Enter loop count: ");
 scanf("%d", &count);

 for(int i=0; i<count; i++)
 {
  testFoo++;
 }

 printf("Value: %d\n", testFoo.GetData());
}

Whether you do ++testFoo or testFoo++, you'll still get the same resulting code. In fact, without reading the count in from the user, the optimizer got the whole thing down to a constant. So this:

for(int i=0; i<10; i++)
{
 testFoo++;
}

printf("Value: %d\n", testFoo.GetData());

Resulted in the following:

00401000  push        0Ah  
00401002  push        offset string "Value: %d\n" (402104h) 
00401007  call        dword ptr [__imp__printf (4020A0h)]

So while it's certainly the case that the postfix version could be slower, it may well be that the optimizer will be good enough to get rid of the temporary copy if you're not using it.

James Sutherland
You forgot to note the important point that here everything is inlined. If the definitions of the operators is not available, the copy done in the out-of-line code cannot be avoided; with inlining the optim is quite obvious, so any compiler will do it.
Blaisorblade
A: 

An the reason why you ought to use ++i even on built-in types where there's no performance advantage is to create a good habit for yourself.

Josh
Sorry, but that bothers me. Who says it's a "good habit", when it almost never matters? If people want to make it part of their discipline, that's fine, but let's distinguish significant reasons from matters of personal taste.
Mike Dunlavey
A: 

@wilhelmtell

The compiler can elide the temporary. Verbatim from the other thread:

The C++ compiler is allowed to eliminate stack based temporaries even if doing so changes program behavior. MSDN link for VC 8:

http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx

MSN

Mat Noguchi
That's not relevant. NRVO avoids the need to copy t in "C C::operator++(int)" back to the caller, but i++ will still copy the old value on the stack of the caller. Without NRVO, i++ creates 2 copies, one to t and one back to the caller.
Blaisorblade
+2  A: 

There's something about it on Google c++ coding style document.

martjno
"Decision: For simple scalar (non-object) values there is no reason to prefer one form and we allow either. For iterators and other template types, use pre-increment."
Nosredna
+2  A: 

I would like to point out an excellent post by Andrew Koenig on Code Talk very recently.

http://dobbscodetalk.com/index.php?option=com_myblog&amp;show=Efficiency-versus-intent.html&amp;Itemid=29

At our company also we use convention of ++iter for consistency and performance where applicable. But Andrew raises over-looked detail regarding intent vs performance. There are times when we want to use iter++ instead of ++iter.

So, first decide your intent and if pre or post does not matter then go with pre as it will have some performance benefit by avoiding creation of extra object and throwing it.

+1  A: 

@Ketan

...raises over-looked detail regarding intent vs performance. There are times when we want to use iter++ instead of ++iter.

Obviously post and pre-increment have different semantics and I'm sure everyone agrees that when the result is used you should use the appropriate operator. I think the question is what should one do when the result is discarded (as in for loops). The answer to this question (IMHO) is that, since the performance considerations are negligible at best, you should do what is more natural. For myself ++i is more natural but my experience tells me that I'm in a minority and using i++ will cause less metal overhead for most people reading your code.

After all that's the reason the language is not called "++C".[*]

[*] Insert obligatory discussion about ++C being a more logical name.

Motti
@Motti: (joking) The C++ name is logical if you recall Bjarne Stroustrup C++ initially coded it as a pre-compiler generating a C program. Hence C++ returned an old C value. Or it may be to enhance that C++ is somewhat conceptually flawed from the beginning.
kriss
+1  A: 

Mark: Just wanted to point out that operator++'s are good candidates to be inlined, and if the compiler elects to do so, the redundant copy will be eliminated in most cases. (e.g. POD types, which iterators usually are.)

That said, it's still better style to use ++iter in most cases. :-)

0124816
+1  A: 

From the c++ faq lite (13.15):

++i is sometimes faster than, and is never slower than, i++.

For intrinsic types like int, it doesn't matter: ++i and i++ are the same speed. For class types like iterators or the previous FAQ's Number class, ++i very well might be faster than i++ since the latter might make a copy of the this object.

The overhead of i++, if it is there at all, won't probably make any practical difference unless your app is CPU bound. For example, if your app spends most of its time waiting for someone to click a mouse, doing disk I/O, network I/O, or database queries, then it won't hurt your performance to waste a few CPU cycles. However it's just as easy to type ++i as i++, so why not use the former unless you actually need the old value of i.

So if you're writing i++ as a statement rather than as part of a larger expression, why not just write ++i instead? You never lose anything, and you sometimes gain something. Old line C programmers are used to writing i++ instead of ++i. E.g., they'll say, for (i = 0; i < 10; i++) .... Since this uses i++ as a statement, not as a part of a larger expression, then you might want to use ++i instead. For symmetry, I personally advocate that style even when it doesn't improve speed, e.g., for intrinsic types and for class types with postfix operators that return void.

Obviously when i++ appears as a part of a larger expression, that's different: it's being used because it's the only logically correct solution, not because it's an old habit you picked up while programming in C.

luke
A: 

The intended question was about when the result is unused (that's clear from the question for C). Can somebody fix this since the question is "community wiki"?

About premature optimizations, Knuth is often quoted. That's right. but Donald Knuth would never defend with that the horrible code which you can see in these days. Ever seen a = b + c among Java Integers (not int)? That amounts to 3 boxing/unboxing conversions. Avoiding stuff like that is important. And uselessly writing i++ instead of ++i is the same mistake.

Even the fact that people are more used to i++ is an unfortunate C legacy, caused by a conceptual mistake by K&R (if you follow the intent argument, that's a logical conclusion; and defending K&R because they're K&R is meaningless, they're great, but they aren't great as language designers; countless mistakes in the C design exist, ranging from gets() to strcpy(), to the strncpy() API (it should have had the strlcpy() API since day 1)).

Btw, I'm one of those not used enough to C++ to find ++i annoying to read. Still, I use that since I acknowledge that it's right.

Blaisorblade
I see you're working on a Ph.D. with interest in compiler optimization and things of that sort. That's great, but don't forget academia is an echo chamber, and common sense often gets left outside the door, at least in C.S. You might be interested in this: http://stackoverflow.com/questions/1303899/performance-difference-between-iterator-and-iterator/1314343#1314343
Mike Dunlavey
+1  A: 

@Mark: I deleted my previous answer because it was a bit flip, and deserved a downvote for that alone. I actually think it's a good question in the sense that it asks what's on the minds of a lot of people.

The usual answer is that ++i is faster than i++, and no doubt it is, but the bigger question is "when should you care?"

If the fraction of CPU time spent in incrementing iterators is less than 10%, then you may not care.

If the fraction of CPU time spent in incrementing iterators is greater than 10%, you can look at which statements are doing that iterating. See if you could just increment integers rather than using iterators. Chances are you could, and while it may be in some sense less desirable, chances are pretty good you will save essentially all the time spent in those iterators.

I've seen an example where the iterator-incrementing was consuming well over 90% of the time. In that case, going to integer-incrementing reduced execution time by essentially that amount. (i.e. better than 10x speedup)

Mike Dunlavey