27

I'm well aware that in C++

int someValue = i++;
array[i++] = otherValue;

has different effect compared to

int someValue = ++i;
array[++i] = otherValue;

but every once in a while I see statements with prefix increment in for-loops or just by their own:

for( int i = 0; i < count; ++i ) {
     //do stuff
}

or

for( int i = 0; i < count; ) {
    //do some stuff;
    if( condition ) {
        ++i;
    } else {
        i += 4;
    }
}

In the latter two cases the ++i looks like an attempt to produce smarty-looking code. Am I overseeing something? Is there a reason to use ++i instead of i++ in the latter two cases?

tshepang
  • 12,111
  • 21
  • 91
  • 136
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 2
    Why use `i++` instead of `++i` in cases where the value is not used anywhere else in the statement? – dave4420 Sep 08 '09 at 09:22
  • "an attempt to produce smarty-looking code" - this this question some kind of inverse snobbery? ;-) – Steve Jessop Sep 08 '09 at 09:43
  • @onebyone: Yes, since IMO the simpler the code looks the better which translates into "don't make me think". – sharptooth Sep 08 '09 at 09:57
  • 3
    I don't think i++ is "simpler" than ++i. How can it be? While it's quite possibly true that ++i makes you think, and even that it makes the majority of people think, I believe that has more to do with your (and their) resistance to using it, than it has to do with the operator itself. I read "++i" as "increment i", and I genuinely don't understand the problems it seems to cause people who quite happily use the trinary ?: operator ;-p – Steve Jessop Sep 08 '09 at 10:13
  • 6
    Or to put it another way - you have developed one habit, which is to use i++ in loops when you could use ++i. You therefore find the alternate habit, using "++i", jarring. But the whole argument against ++i consists of, "we're used to using i++". The argument against i++ consists of, "it's sometimes less efficient, for no gain other than familiarity". So the question is whether to replace one habit with another. I think familiarity is a bogus reason for sticking with a "bad" habit. Non-trivial iterators have existed in C++ for 10 years now, which is long enough to relearn a habit. – Steve Jessop Sep 08 '09 at 10:23
  • 1
    "trinary operator" - ternary operator, even. Stupid English language. – Steve Jessop Sep 08 '09 at 10:25

7 Answers7

50

Look at possible implementations of the two operators in own code:

// Pre-increment
T*& operator ++() {
    // Perform increment operation.
    return *this;
}

// Post-increment
T operator ++(int) {
    T copy = *this;
    ++*this;
    return copy;
}

The postfix operator invokes the prefix operator to perform its own operation: by design and in principle the prefix version will always be faster than the postfix version, although the compiler can optimize this in many cases (and especially for builtin types).

The preference for the prefix operator is therefore natural; it’s the other that needs explanation: why are so many people intrigued by the use of the prefix operator in situations where it doesn’t matter – yet nobody is ever astonished by the use of the postfix operator.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 17
    Because C++ is standard, but who has heard of ++C? – MaxVT Sep 08 '09 at 09:23
  • 12
    If you're going to wildly fantasise that the name of the C++ language actually has any bearing on how code should be written, then that name should be C+1, since mentioning it does not in point of fact modify the C language every time... – Steve Jessop Sep 08 '09 at 10:21
  • And yet I always get weird reactions when someone stumbles upon my for-loops with prefix increments. – Jules Dec 14 '10 at 17:11
  • @Jules: weird reactions from whom? Java/C#/C folks, perhaps. Certainly not from experienced C++ programmers. – Konrad Rudolph Dec 14 '10 at 18:44
  • Mostly Java, C# and PHP folks. I never worked with C++ on a professional level, therefore have little contact with C++ experts. I started doing it when I learned about operator overloading at uni and been using it in any kind of C-syntax language ever since. Even though it doesn't yield any benefits, due to compiler optimisation. So much for the tale telling. To support your point: pre- and postfix notation IMO convey a certain meaning, so I agree with you 100% - using the postfix style is the actual "perversion". – Jules Dec 14 '10 at 21:16
40

If we ignore force of habit, '++i' is a simpler operation conceptually: It simply adds one to the value of i, and then uses it.

i++ on the other hand, is "take the original value of i, store it as a temporary, add one to i, and then return the temporary". It requires us to keep the old value around even after i has been updated.

And as Konrad Rudolph showed, there can be performance costs to using i++ with user-defined types.

So the question is, why not always just default to ++i?

If you have no reason to use `i++´, why do it? Why would you default to the operation which is more complicated to reason about, and may be slower to execute?

jalf
  • 243,077
  • 51
  • 345
  • 550
7

As you noted - it does not matter to the result.

There is a performance consideration for non-primitive types.

Also semantically using pre-increment is usually clearer in showing the intention of a test when the return value is used, so its better to use it habitually than post-increment to avoid accidentally testing the old value.

Timothy Pratley
  • 10,586
  • 3
  • 34
  • 63
  • Not true; Sometimes it does make a difference. For example; x = (++x % 10), in which x cycles from 0 through 9, won't work if you use post increment. There are examples where the reverse is true. It's important to know the difference and "say what you mean" rather than hope the optimiser guesses correctly for you. – Chris Huang-Leaver Sep 08 '09 at 12:58
  • Hi Chris - your comment doesn't seem relevant. The question is about cases where using either ++x or x++ will give precisely the same result. Clearly the difference is when the result is used or not, and if you are using the result you need to choose the correct one. Perhaps you disagree with my suggestion that it is less clear using post-fix, I guess that is subjective... but I find at first glance it is easy to confuse the meaning of a[x++] = 1 which could be alternatively written as a[x] = 1; ++x; whereas b[++y] = 2 is rarely misunderstood. – Timothy Pratley Sep 08 '09 at 13:36
4

There is one reason, and it has to do with overloaded operators. In an overloaded postincrement function, the function must remember the previous value of the object, increment it, and then return the previous value. In a preincrement function, the function can simply increment the object and then return a reference to itself (its new value).

In the case of an integer, the above probably won't apply because the compiler knows the context in which the increment is being done, and will generate appropriate increment code in either case.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • does this mean that for the example given where i is an int, it's bogus since it won't amount to any additional speedup? – Toad Sep 08 '09 at 09:04
  • I would add that this only applies to objects. I don't think you can overload ++ for an int, can you? It's possible that it might be faster for brain-dead compilers, but any decent compiler should be able to optimize i++ and ++i to the same sequence (for ints, at least). – paxdiablo Sep 08 '09 at 09:04
  • Right, I just amended my answer to include that. – Greg Hewgill Sep 08 '09 at 09:05
  • @Pax: In C++, when you write `int i;`, then `i` is an "object", too. (C++ isn't Java.) – sbi Sep 08 '09 at 09:37
  • @reinier - the argument usually used there is that it's silly to use post-increment for integer and pointer types "because there's no speedup", but then switch to pre-increment for non-trivial iterators. Saying that using ++i is "bogus" where there's no performance difference presupposes that i++ is preferable for other reasons, which is merely an assertion that you don't trust that your colleagues know C well enough to comfortably read whichever. If people were this cautious about readability the rest of the time, I'd have handled a lot less crappy code in my life... – Steve Jessop Sep 08 '09 at 10:31
2

Yes, for performance reasons. In case of post increment a copy of the variable i needs to be made before incrementing so that the old value can be returned (eventhough you are not using the return value). In case of pre-increment this copy is not required.

Naveen
  • 74,600
  • 47
  • 176
  • 233
1

There is little reason to favour pre-increment over post-increment when you are talking about natural types like integers. The compiler is typically able to generate the same code in both cases anyway, assuming you don't use the return value. This is not true for more complex types, such as iterators.

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
  • 1
    True, but it is still better to train yourself to always use the pre-increment form in such cases, rather than think about the variable's type. The code is more consistent, and is robust if the type changes. – tragomaskhalos Sep 08 '09 at 10:02
0

The C++ FAQ Lite has a nice discussion of i++ vs. ++i here:

[13.15] Which is more efficient: i++ or ++i?

In particular, with respect to which form to use within a for loop, the FAQ expresses a preference for ++i. Here's the text:

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.

DavidRR
  • 18,291
  • 25
  • 109
  • 191