-3

I was having a discussion with a stubborn person I know over which of these two forms was more semantically correct, although there is no logical difference to the code:

1.

for(int x = 0; x < 10; x++)
// do something

2.

for(int x = 0; x < 10; ++x)
// do something

Is it better to pre-increment or post-increment in a for loop?

  • 5
    Does this answer your question? [Difference between pre-increment and post-increment in a loop?](https://stackoverflow.com/questions/484462/difference-between-pre-increment-and-post-increment-in-a-loop) – Flori Bruci May 22 '20 at 12:26
  • (2) but when compiled should make no difference. – Mansoor May 22 '20 at 12:27
  • No @FloriBruci that one simply explains the process without commenting on the style of the two alternatives. – Ethereal Unagi May 22 '20 at 12:30
  • This is a very opinion-based question but generally speaking no one cares when it comes to simple integers and Microsoft uses `++it` in their implementation of the standard library whenever the thing getting incremented is an iterator. Make of that what you will. – Big Temp May 22 '20 at 12:39
  • 1
    As a rule of thumb, prefer `++it` over `it++` unless you have a specific reason not to. – Aykhan Hagverdili May 22 '20 at 12:40

4 Answers4

4

If you don't need the side effect of post increment, then the pre increment version is the better choice.

In case of an int it does not result in different code, but in case of an iterator you probably get better performance with pre increment because post increment needs to create a temporary copy of the original iterator. You can easily see that when comparing pre increment

class T {
    T& operator++() {
        this-> .... // do the increment
        return *this;
    }
}

with the post increment

class T {
    T operator++(int) {
        const T old{ *this };
        this-> .... // do the increment
        return old;
    }
}

If the iterator is just a pointer then the compiler might be able to optimize so much that you don't see a difference, but if the iterator is more complex, then you will see a difference.

Of course the same applies to prefix and postfix decrement.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • This depends on the underlying processor architecture and cannot be generalized. – Joel Bodenmann May 22 '20 at 12:28
  • 6
    `but in case of an iterator you probably get better performance with post increment because pre increment needs to create a temporary copy of the original iterator.` Quite the opposite. It is the post increment which necessitates the copy. That said, it too can be optimised away. – eerorika May 22 '20 at 12:32
  • I would say, you expect copying to optimize away. Iterators are designed to be passed by value, so iterators copying is lightweight operation prone to optimization. So actually there's no difference for iterators either. – Alex Guteniev May 22 '20 at 12:36
  • @eerorika Of course, you are right. I corrected my answer. – Werner Henze May 23 '20 at 07:45
2

If a modern compiler with optimisations switched on produces different code for x++ and ++x for this particular case then you ought to switch compiler vendors.

I always write ++x since (i) the type of x might change to a non-POD in the future and x++ could take an expensive copy in such a case, (ii) because it buries a message in your code that you think about things like this, and (iii) because I'm old fashioned.

(I insist on ++x in my company.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Does not matter.

Might matter for iterators instead of ints, but actually does not matter to them either.

I'd yield to a stubborn person.

Or retreat by saying "i += 1" (but that may be worse for iterators)

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
0
// pre-fix operator
MyCustomClass& operator++()
{
    return *this;
}

// post-fix operator
MyCustomClass operator++(int)
{
  MyCustomClass tmp(*this);
  operator++();
  return tmp;
}

and as a best practice:

to be consistent with the built in operators, your built in postfix operator should return the old value, thar value is returned as a value and never as a reference but for prefix operators you should return a reference to the modified object.

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97