§ December 18, 2008

Pre-increment vs post-increment operators

Ok, so here's a question for you that most people should have learned in school, but didn't. You have to answer this without running to visual studio.

  1. What is the difference between ++i and i++?
  2. What is the output of the following piece of code:
for(int i = 0; i < 5; ++i) {
    Console.WriteLine(i);
}
Is it: A)
1
2
3
4
or: B)
0
1
2
3
4
I'm sure there are quite a few who would choose A, but this is in fact incorrect (go ahead and run it in visual studio now).

Most of us when we learned C style programming were taught that pre-increment increments the value before taking the value, and that post increment takes the value then increments. After being taught that, pretty much every professor, every code sample, and everybody under the sun used post increment for every single iterative example in existence.

Question is... WHY?

Inside a loop, I cannot see why anyone would use post increment. What is the order of operation? Declare, loop body, compare, increment, loop body, compare, increment, ....

Unlike C++ (where there are there are actually 2 distinct operators: a pre and a post increment operator) C#, has only one generic "increment" / "decrement" operator, so exactly how the operator works is left completely out of our hands (and is handled internally by the framework). As stated in the ECMA spec (page 176 of the 4th edition of the ECMA-334):
The run-time processing of a postfix increment or decrement operation of the form x++ or x-- consists of the following steps:
  • If x is classified as a variable:
    • x is evaluated to produce the variable.
    • The value of x is saved.
    • The saved value of x is converted to the operand type of the selected operator and the operator is invoked with this value as its argument.
    • The value returned by the operator is converted to the type of x and stored in the location given by the evaluation of x.
    • The saved value of x becomes the result of the operation.
By comparison, here is what is stated for a pre-increment operation (page 196 of ECMA-334 4th edition):
The run-time processing of a prefix increment or decrement operation of the form ++x or --x consists of the following steps:
  • If x is classified as a variable:
    • x is evaluated to produce the variable.
    • The value of x is converted to the operand type of the selected operator and the operator is invoked with this value as its argument.
    • The value returned by the operator is converted to the type of x. The resulting value is stored in the location given by the evaluation of x and becomes the result of the operation.
So in the case of post increment, a copy has to be made, the op_Increment is invoked using the copy, the value is returned, and the copy overwrites the original value.

With pre increment, the value is passed into the op_Increment method, and its value is returned.

In the case of a loop, we are not using the value returned pre-increment, and are therefore only using the increment operation to alter the original value, so using post increment is completely pointless. Why anyone uses it is beyond me. Maybe its a case of not actually understanding whats going on.

There are a few places where it actually makes sense to use a post increment operation, but even these probably have better solutions to them as well:
int i = 0;
int j = i++;
// or
int[] table = { 0, 1, 2, 3, 4, 5, 6 };
int i = 0;
int j = table[i++];
int k = table[i++];
int l = table[i++];
So the moral of the story is... post increment wisely (have a good reason to use it, otherwise pre-increment).
Posted 16 years, 6 months ago on December 18, 2008

 Comments can be posted in the forums.

© 2003 - 2024 NullFX
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License