Pre- and Post-Incrementing Sheep
I got distracted on Stack Overflow again today. This time, it was reading a thread on the subject Great programming quotes. Here’s my pick:
A programmer started to cuss
Because getting to sleep was a fuss
As he lay there in bed
Looping ’round in his head
was: while(!asleep()) sheep++;
I thought it was pretty clever (it made me chuckle at least). And when I read this comment…
I would use “++sheep”, rather than “sheep++”. It will do less copying, which is important because a sheep is a pretty complex object.
I absolutely fell over laughing. I don’t think any hard core dev would have trouble seeing the epic humor in this logical critique of the poor restless programmers’ toSleep() function. However, my laughing fit was short-lived. Because, nearly as quickly as the humor sank in, another feeling began crowding it out: uncomfort. I didn’t quite know why. I read the comment again, and instantly knew why my Spidey sense had been tingling.
sheep, as presented, would clearly be some form of integer. Actually, unsigned integer (if you don’t want to run certain risks). And in the case of incrementing* a lone integer (meaning, it isn’t being used as part of a more complex expression) there won’t be much difference here. However, it’s a good platform off of which to launch a discussion about the semantics between pre- and post-increment operators.
At it’s easiest, here’s the difference:
- Pre-increment (as in
++x) increments the value ofx, and then returns the new value, as opposed to - Post-increment (as in
x++) which increments the value ofx, but returns it’s old value
Here’s an example:
int x = 4; int y = x++;
Here, y will wind up with a value of 4, and x will end up holding a 5. When we use pre-increment though, as in:
int x = 4; int y = ++x;
Both x and y will hold a value of 5.
The latter method is the faster of the two, and the reason is pretty simple. In order for the post-increment operator to work, it must first store a temporary copy of the value, increment, and then return the copy. The pre-increment implementation simply increments and then returns itself. In that, our comedic commenter was correct – the pre-increment operator can be faster than post-increment. However most compilers will automatically optimize an increment statement [if they can do so without altering the semantics of the code]. And, in the case of
if ( !asleep() ) sheep++;
the compiler would most certainly do so. So, while our amusing annotator had the right idea, unfortunately he was a bit mislead in this case.
Still, I think it’s a riot.
*I use the case of pre- and post-increment here for brevity. The same mechanics are at work for the pre- and post-decrement operators.