+5  A: 

The obvious is when you want the old value returned, you use post-increment.

The more subtle things are that pre-increment should really never be slower and could be faster due to the lack of creating a temporary and returning the old value when using post-increment.

A real scenario for using post-increment in C++ is when erasing from standard containers. For example:

set<int> ctr;
ctr.insert(1);
ctr.insert(10);
ctr.insert(12);
ctr.insert(15);

set<int>::iterator it = set.begin();

// Post-increment so the value returned to erase is that of the previous
// iteration (i.e. begin()), yet the iterator stays valid due to the local
// iterator being incremented prior to the erase call
ctr.erase(it++);

// Still valid iterator can be used.
cout << "Value: " << *it << "\n";  

In response to the compiler optimization, it is true yet I think it's always important to convey as precisely as possible what you're trying to accomplish. If you don't need the returned value from x++, then don't ask for it. Also, I'm not sure you would always get the same optimization if the type your incrementing is not a simple type. Think iterators that are not just plain pointers. In cases such as this, your mileage may vary with regard to optimization. In short, always pre-increment unless you need the returned (i.e. old value) of the post-increment operator.

RC
+1 for the subtle optimization tip.
David Young
Actually, I think almost every compiler will optimize `i++` to `++i` under the usual circumstances (where the result of the operation is ignored and `i` has no overloaded increment/decrement operators). That said, I still prefer to pre-increment/decrement instead of post-incrementing/decrementing, as I think it convoys the meaning of the action better. And you likely *will* see a speed up if `i` does happen to be a user-defined type with custom `++`/`--` operators.
bcat
@bcat agree with you..in most cases it just makes sense to pre-increment, not sure why this is such a big deal when they teach at schools.
CodeToGlory
@CodeToGlory: I don't know. At my school all the CS professors use post-increments, even in for-loops. It drives me kind of insane, to be honest. :)
bcat
I've updated my response for bcat's comment
RC
This is interesting given how much may go on with a "simple" `++/--` in C++, but when you're using plain int, especially in C (not C++) the difference is negligible, and *especially* with PDP/VAX-11 architecture where register pre/post-increment/decrement are directly supported, and I'd guess that's why the CS profs use post-increments.
Stephen P
For me it's a legibility thing, `i++` is almost always more readable; see my response
Zack
`std::set` is somewhat special because its `erase` doesn't invalidate iterators. There are more containers like that, but not all of them. `std::vector` might surprise unaware reader. It would be nice if you explained that. Right now you say about "standard containers".
Maciej Hehl
@maciej - I see your point where my statement about STD containers could be misinterpreted. To clarify std::set, it does invalidate the iterator being erased and thus post increment above must be used or a later use of the iterator would lead to undefined behavior. I believe this type of example is what the OP was looking for.
RC
@Stephen P: I hadn't thought of that, but it makes a lot of sense. I know all my profs have worked on their fair share of older hardware, so it stands to reason that it would heavily influence their coding style.
bcat
+2  A: 

The best explanation in order to clarify the differences is:

  • i++ - use the value of i for whatever value it holds, then take the value of i, increment it, and store it
  • ++i - increment the value of i and store it immediately then use that value.

That is the crucial difference one increments AFTER the statement is evaluated, the other is incremented BEFORE the statement is evaluated.

tommieb75
+2  A: 

I prefer to use i++ unless I specifically need the behavior of ++i, because that puts the variable on the left, consistent with i += N. Mostly this is minor, but in for-loops, I consider ++i to be wrong and will change it to i++ en passant, because

for (i = 0; i < limit; ++i)

trips the reader up with lack of parallel structure;

for (i = 0; i < limit; i++)

is much nicer to read, because the loop variable is in the same position in all three clauses.

Arguments from performance are hogwash. Any compiler worth its salt will generate exactly the same code in cases where the difference doesn't matter. Yes, that includes cases involving C++ overloaded operators.

Zack