I’m a bit late posting this, but that’s been my schedule lately.
A few weeks ago, Cori Drew started quite the conversation on twitter about ++x and x++ .
I summarized the behavior in this github gist.
About the same time, Michael Letterle wrote a gist that summarized some of the same information:
Let’s summarize the behavior that every C# developer should remember:
- ++x evaluates to the value of x after it has been incremented.
- x++ evaluates to the value of x before it has been incremented.
- Both versions mutate x, and x now has the value of x incremented by one (however that is defined for the type of x)
What I found very interesting in the discussion is how this starts to confuse people when this feature is combined with other language features.
One of the side-trips involved using named parameters to pass parameters to a method in a different order. The parameters are evaluated in the order they appear on the method call, not the order they appear in the method definition. Most developers can safely ignore this fact. Most of the time, the order that parameters appear is positional, so it’s the same result. And, it only causes an actual difference if the same object is mutated at the call site (as I show intentionally in my gist).
In an interesting bit of serendipity, Eric Lippert covered the C# rules in more detail in “Ask the Bug Guys” on the Coverity blog. Eric goes into a bit more detail about the behavior of x++ vs. ++x, and how that affects the way you would write an overloaded increment operator in C#. He discusses new rults that you must remember when you are overloading the ++ operator in your types. In particular (from the above referenced post:
- a user defined ++ operator in C# should never be used to mutate the state of the operand.
- restrict overloading++ to types that are logically numbers of some sort.
Remember the simple rules, and know where to look in the spec for those rules you need occasionally. The language designers (not just for C#) work hard to make language rules consistent, and as unsurprising as possible. We all keep learning, but with well-designed languages make it easier to build new knowledge on the knowledge you already have.