Why you should use prefix increments instead of postfix

This is a pet peeve of mine, so bear with me. I really don’t like this code (curly brace language of your choice, but lets say it’s C#):

for (int i = 0; i < 10; i++)
{
   // Do stuff
}

I specifically do not like i++. If you don’t have a really good reason you should be writing ++i in almost every case. Even when it doesn’t matter, like in the example above, simply because it’s good style to do so.

The result in the loop above is exactly the same if it’s written like this:

for (int i = 0; i < 10; ++i)
{
   // Do stuff
}

So why does it matter? Because sooner or later it will bite you in the ass. You see i++ has the connotation that the l-value of any expression that uses it is the value before it was incremented. Which means that a copy must be made. Sure, the compiler probably optimizes this away, but what if this was an operator overloaded object?

Take a look at this, admittedly stupid but possible, object

public class Overloaded
    {
        private ExpensiveObjectToManipulate junk;

        static public Overloaded operator ++(Overloaded o)
        {
            o.junk.Increase();
            return o;
        }
    }

You see C# only provides one overload method for ++. In glorious C++ you get to overload it twice, in which case you also get the great opportunity to also mess up the semantics of the action. Or change the return type or other generally retarded actions C++ allows. But I digress.

So, C# gives you both prefix and postfix increment for an overload. Prefix does what you think it does. Postfix does not. Postfix will make a copy of the object, assign it to whatever is supposed to be the target of the expression then it will perform the operation on the ExpensiveObjectToManipulate. Now think about if you are using the Overloaded object in a loop. And ExpensiveObjectToManipulate is also expensive as hell to copy. It might be copied by value?

Do you trust your compiler to optimize it away?

Do you trust your vendor of stupid overloaded objects to not have different side effect from the copying?

This might not be a big problem in C# where this sort of operator overloading thankfully is rare, but if you ever get to the wonderful world of C++ you’re going to see this. There is no reason on this earth to use postfix operator with it’s inherent complications in so many cases.

var i = new Overloaded();  // Using fun object for making a point.
foreach (var x in collectionOfX)
{
   // Do stuff with x
   x.DoStuff();
   // increase the counter
   i++; // Why, oh gods, why?!?
} 

There is no reason to use the postfix! Yet I’m willing to bet that many of you are doing it. Same goes for every for loop. So let’s do the safe and optimized thing and use our friend the prefix operator every time you don’t mean to copy things.

Advertisements
Tagged , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: