0

These days I see this very often:

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

Rather than - as was very much the fashion (?) 20 years ago - this:

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

Is there a reason for this change or is it just fashion?

(There is a similar question about Java here but I don't think the answers get to the heart of the matter)

adrianmcmenamin
  • 1,081
  • 1
  • 15
  • 44

2 Answers2

3

C and C++

Post-increment involves a temporary that can be avoided by using pre-increment (Post-increment and Pre-increment concept?).

C++

If only integers are involved, the issue is not that critical and the compiler can probably optimize both versions to do essentially the same. However, in C++ basically any object of class type can have a ++ (both post- and pre-) and that can be overloaded to do basically anything. Post-incrementing a big object has a cost and depending on how to operator is implemented the compiler might not be able to optimize both post- and pre-increment to do essentially the same thing. To be on the save side it is prefered to use ++i.

20 years ago

Actually the only thing that changed with respect to this issue is that compiler optimizations got much better over time. I didn't check any old compiler, but I would say that 20 years ago missing compiler optimizations were a much stronger reason to use ++i instead of i++. Maybe what you observed is just style of code getting better.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • This answer misses the fact that there will assuredly be no "cost" here. The semantics, all things considered, are entirely equivalent (as the evaluation result is unused), and the produced code will be identical. It's more for consistency, most likely, along with misunderstandings (people _thinking_ it'll save them performance) – Asteroids With Wings Apr 27 '20 at 10:09
  • @AsteroidsWithWings Not in C++, the `++` might be overloaded differently when used as pre- or as post-increment. I think the *real* reason is that `++i` is common in C++ (because of this difference + optimization or even premature optimization) and `i++` in C code as it's no issue there at all. – ljrk Apr 27 '20 at 13:21
  • @larkey Look up the "as-if" rule. When you're writing C++, you are not specifying a sequence of instructions for your computer to perform. You are _describing a program_. If the evaluated result of post-increment is not used, there is no need for the intermediate result, and your compiler is smart enough to realise that. (Some people call this "optimisation".) If there is an unidiomatic overload, though, with side effects, then yes those side effects must be performed, and I did say that in my answer ;) You can't overload pre- or post-increment for `int` though. – Asteroids With Wings Apr 27 '20 at 13:36
  • @AsteroidsWithWings I only read your comment which said that the semantics are equivalence which doesn't need to hold in C++ for all types, if you overload in a way to have side-effects. That way, the semantics are different regardless of the ignored evaluation of the expression. And thus you have this distinction in C++ but not in C. – ljrk Apr 27 '20 at 18:50
  • @larkey Indeed; I literally just said that. – Asteroids With Wings Apr 27 '20 at 19:06
2

It's mostly fashion, but also a combination of consistency and misunderstanding.

When iterators came along, and more and more people started realising that ++it could be cheaper than it++, for some more-complex-than-a-pointer iterator it, they started getting into the habit of pre-incrementing everywhere, to save what they perceived to be unnecessary copies in the semantics of a post-increment (the original value would have to be stored temporarily for returning after the increment occurs). They'd then do that for integers too, because why not?

In reality, there's nothing to save. Your compiler is perfectly capable of spotting that the evaluated result is never used here, so ++it and it++ in this context have exactly identical semantics (unless there is some non-idiomatic side effect in the definition of the operator). This is particularly the case for a simple integer i.

It doesn't hurt, of course, and it does eliminate the risk that you've missed some weird angle that does result in an unnecessary copy. It's a good practice. It's just that it hasn't come about out of necessity.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35