views:

733

answers:

8

Hello, I'm currently learning C++ and I've learned about the incrementation a while ago. I know that you can use "++x" to make the incrementation before and "x++" to do it after.

Still, I really don't know when to use which... I've never really used "++x" and things always worked fine so far, but when should I use it?

Exemple : In a for loop, when is it preferable to use "++x"?

Also, could someone explain exactly how the different incrementations(or decrementations) work? I would really appreciate.

Thanks for your help :) .

+9  A: 

It's not a question of preference, but of logic.

x++ increments the value of variable x after processing the current statement.

++x increments the value of variable x before processing the current statement.

So just decide on the logic you write.

x += ++i will increment i and add i+1 to x. x += i++ will add i to x, then increment i.

BeowulfOF
and please note that in a for loop, on primatives, there is absolutely no difference.Many coding styles will recommend never using an increment operator where it could be misunderstood; i.e., x++ or ++x should only exist on its own line, never as y=x++. Personally, I don't like this, but it's uncommon
Mikeage
And if used on its own line, the generated code is almost sure to be the same.
Nosredna
This may seem like pedantry (mainly because it is :) ) but in C++, `x++` is a rvalue with the value of `x` before increment, `x++` is an lvalue with the value of `x` after an increment. Neither expression guarantees when the actual incremented value is stored back to x, it is only guaranteed that it happens before the next sequence point. 'after processing the current statement' is not strictly accurate as some expressions have sequence points and some statements are compound statements.
Charles Bailey
Actually, the answer is misleading. The point in time where the variable x is modified probably doesn't differ in practice. The difference is that x++ is defined to return an rvalue of the previous value of x while ++x still refers to the variable x.
sellibitze
@Charles: You're absolutely right to be "pedantic" here. Sequence points etc. are not well understood and especially that this has been marked as the answer it should be fixed.
Richard Corden
@BeowulfOF: I really think it worth rewording your answer so that it does not imply when the side-effects take place....
Richard Corden
what side effects? I mean what goes on inside is less important if the effect seen is correct, isn't it? The answer from duffymo says exact the same thing only as quote from a book.
BeowulfOF
@BeowulfOF: The answer implies an order which doesn't exist. There is nothing in the standard to say when the increments take place. The compiler is entitled to implement "x += i++" as: int j = i; i=i+1 ; x += j;" (ie. 'i' incremented before "processing the current statement"). This is why "i = i++" has undefined behaviour and its why I think the answer needs "tweaking". The description of "x += ++i" is correct as there is no suggestion of order: "will increment i and add i+1 to x".
Richard Corden
you are using the same words: "'i' increments before processing the current statement" - I do not imply when exactly the increment is done - but the variable is incremented before processing the statement (++i) or the statement is processed before the increment is done (i++) -> to work with it its correct and easy to remember, no words about exactly when the increment is done or whether additional helper vars are used.
BeowulfOF
@BeowulfOF: In my comment, my words refer to the code in the comment, and I explicitly use those words as they say they contradict the words you've used in your answer. And yet again in your comment you've said: "but the variable is incremented before processing the statement (++i)". This is just not true. The result of (++i) be "i+1" but there's no guarantee that the variable will have this value at that time. The expression "x+= <result>" can be evaluated, x modified and *THEN* 'i' updated.
Richard Corden
+13  A: 

Scott Meyers tells you to prefer prefix except on those occasions where logic would dictate that postfix is appropriate.

"More Effective C++" item #6 - that's sufficient authority for me.

For those who don't own the book, here are the pertinent quotes. From page 32:

From your days as a C programmer, you may recall that the prefix form of the increment operator is sometimes called "increment and fetch", while the postfix form is often known as "fetch and increment." The two phrases are important to remember, because they all but act as formal specifications...

And on page 34:

If you're the kind who worries about efficiency, you probably broke into a sweat when you first saw the postfix increment function. That function has to create a temporary object for its return value and the implementation above also creates an explicit temporary object that has to be constructed and destructed. The prefix increment function has no such temporaries...

duffymo
I don't own that book, is there a reason for that?
Lucas
Inuitively agreed with Scott Meyers, prefix is straighforward
LarsOn
If the compiler doesn't realize that the value before the increment is unnessescary, it might implement the postfix increment in several instructions - copy the old value, and then increment. The prefix increment should always just be one instruction.
gnud
+1  A: 

You explained the difference correctly. It just depends on if you want x to increment before every run through a loop, or after that. It depends on your program logic, what is appropriate.

An important difference when dealing with STL-Iterators (which also implement these operators) is, that it++ creates a copy of the object the iterator points to, then increments, and then returns the copy. ++it on the other hand does the increment first and then returns a reference to the object the iterator now points to. This is mostly just relevant when every bit of performance counts or when you implement your own STL-iterator.

Edit: fixed the mixup of prefix and suffix notation

Space_C0wb0y
Wow, I had no idea.
Lucas
you got the iterator stuff exactly the wrong way round. `++i` is faster, because it will not copy the object, `i++` is slower, because it first creates a copy of the object, increments the iterator and then return the copied object (which is still in the same state)
knittl
You are right, it's the wrong way. I apologize for the mixup.
Space_C0wb0y
+1  A: 

I agree with @BeowulfOF, though for clarity I would always advocate splitting the statements so that the logic is absolutely clear, i.e.:

i++;
x += i;

or

x += i;
i++;

So my answer is if you write clear code then this should rarely matter (and if it matters then your code is probably not clear enough).

Bids
+1  A: 

Just wanted to re-emphasize that ++x is expected to be faster than x++, (especially if x is an object of some arbitrary type), so unless required for logical reasons, ++x should be used.

Shailesh Kumar
+5  A: 

From cppreference when incrementing iterators:

You should prefer pre-increment operator (++iter) to post-increment operator (iter++) if you are not going to use the old value. Post-increment is generally implemented as follows:

   Iter operator++(int)   {
     Iter tmp(*this); // store the old value in a temporary object
     ++*this;         // call pre-increment
     return tmp;      // return the old value   }

Obviously, it's less efficient than pre-increment.

Pre-increment does not generate the temporary object. This can make a significant difference if your object is expensive to create.

Phillip Ngan
+5  A: 

I just want to notice that the geneated code is offen the same if you use pre/post incrementation where the semantic (of pre/post) doesn't matter.

example:

pre.cpp:

#include <iostream>

int main()
{
  int i = 13;
  i++;
  for (; i < 42; i++)
    {
      std::cout << i << std::endl;
    }
}

post.cpp:

#include <iostream>

int main()
{

  int i = 13;
  ++i;
  for (; i < 42; ++i)
    {
      std::cout << i << std::endl;
    }
}

_

$> g++ -S pre.cpp
$> g++ -S post.cpp
$> diff pre.s post.s   
1c1
<   .file "pre.cpp"
---
>   .file "post.cpp"
chub
For a primitive type like an integer, yes. Have you checked to see what the difference turns out to be for something like a `std::map::iterator`? Of course there the two operators are different, but I'm curious as to whether the compiler will optimize postfix to prefix if the result is not used. I don't think it's allowed to -- given that the postfix version could contain side effects.
seh
+1  A: 

The most important thing to keep in mind, imo, is that x++ needs to return the value before the increment actually took place -- therefore, it has to make a temporary copy of the object (pre increment). This is less effecient than ++x, which is incremented in-place and returned.

Another thing worth mentioning, though, is that most compilers will be able to optimize such unnecessary things away when possible, for instance both options will lead to same code here:

for (int i(0);i<10;++i)
for (int i(0);i<10;i++)
rmn