Thursday, April 10, 2008

How I tell ++preincrement and postincrement++ apart.

The rules of C operators are byzantine; the best thing you can say about them is that they make some idioms very terse, e.g.
while(*p++) { }
You could go crazy trying to remember the operator precedent rules if you don't use them all the time. But the way I remember the two forms of ++ gets at a deeper issue, so it's more than just C trivia.

First, let us recall that ++a will increment the variable a and return the new value; a++ will increment a adn return the old value. I suppose that Kernigan and Richie, while "designing C" (between bong hits) thought that having the ++ after a would help make it clear that the increment happened after, um, other stuff. In partiular, while(*a++) evaluates the thing pointed to by a for not being zero before incrementing. (But then it increments no matter what. Cute.)

I suspect that I am like virtually all C programmers in that I learned to use post-increment for whatever reason, e.g.
for (n = 0; n < 5; n++)
Now step into the world of C++. Consider the implementation of ++ when our variable is not a simple integer, but rather a very expensive C++ object.

The pre-increment is easy. We change our object to be one more, and then that object is used in the next expression. But post-increment is a lot more expensive. We have to...
  1. Make a new object that is a copy of the object that is being incremented.
  2. Increment the old object.
  3. Use the new object later in the expression.
  4. The new object is in fact a temporary variable invented by the compiler, so it will get destroyed.
In fact, it's even worse...because of the way the operators are written, there will actually be two temporary variables, two copies, and two destroys. If creating, or deleting copies of your object is even remotely expensive, post-increment is much more expensive than pre-increment.

And in that is both a lesson in C++ and how to remember what's going on. In three parts:
  1. Always default to using pre-increment when you can. Make it a habbit to pre-increment, because post-increment can cost you and pre-increment never will.
  2. Remember that post-increment is the "expensive" one, that's how you can tell them apart.
  3. The more expensive post-increment also has the weirder signature when overloaded, e.g. operator++(int), not just operator++().

No comments:

Post a Comment