I have lots of time to think when I drive back and forth to and from school. Today I examined my preference for i++ over ++i when they accomplish the same thing.
I've noticed that for some strange reason, I tend to both type, and think rhythmically. When I program, I sometimes silently say to myself what I am write. One of the main factors,, I presume, in my preference, is that ++i is easier to say. It rolls off the tongue smoother.
Secondly, I think that ++i is easier to type than i++. Well, at least ++somevar. When you are to make the decision to type a variable increment, you know before you start that you will be typing ++. Before you have even fully realized the name of the specific variable, you can have already instinctually typed your ++. I personally have a strange style of typing where I tend to rest my pinky on the shift key in between thoughts / sentences / statements. Probably this comes from the fact that sentences start with capital letters. This means that my pinky usually in a more suited position to begin to type ++ than it will be immediately after typing some identify.
There it is. That is why only fools use i++ in preference of ++i;) And those are the types of pointless thoughts the run through my brain while it sits idle.
a = b++; // can be processed in 1 CPU cycle, inc and mov executed on different pipelines
a = ++b; // forces RAW and possible pipeline stall
I know they are both doing slightly different thing, but if you can decide, you should always use post-increment where possible (applies to primitive types only).
They aren't doing slightly different things. They are doing different things.
Obviously where context matters, you use the one that is appropriate. Where context doesn't matter, it's perfectly efficient to use either in the case of native types and more efficient in many cases to use the prefix version with user-defined types. So, it's reasonable to prefer ++i when context doesn't matter, because the compiler will generate the same code for native types and the most efficient code for user-defined types.
@ rapidcoder: That's a valid point. My understanding of low level pipelinine behavior is admittedly less than I'd like.... but AFAIK it's impossible to accomplish a = ++b without the possible pipeline stall no matter what you do. For example:
a = b;
This code will have the same effect (by using the postfix version), and the same read/write, and therefore the same potential pipeline stall.
So it's not that prefix is any slower than postfix. It's just that modifying a variable right before reading it is slower.
So I'm standing by my original statement.
Though I welcome further discussion on the topic. Especially if my understanding is incorrect.
Just like with many other things that are 'good habit', I use pre-increment and pre-decrement because it is a 'good habit', as explained in Disch's original post. There are times when I use post-increment or post-decrement, like mymap.erase(it++); because I use the return value of the previous state.
I do have to wonder, in C++11, is there some way to optimize overloaded post-increment/decrement operators? it seems like the making a copy and changing the state is a prime candidate for move constructing but I don't see how it could be easily done without some memory magic.
You should never ever do that. It's very bad. Iterators become invalid once you erase them, and incrementing an invalid iterator is undefined.
That is actually perfectly valid for containers that don't invalidate iterators to other elements in the container when erase is used. it is advanced before the map element is erased. erase works on a (temporary) copy.
It's good not to be in the habit of doing that though, because it's obviously not safe on all containers.