Now I'll do something that shouldn't be done... I'll try to simplify what Eric Lippert wrote here What is the difference between i++ and ++i? I hope I'm not writing anything too much wrong :-)
Now... What does the pre-increment and post-increment operators do? Simplifying and ignoring all the copy that are done in-between (and remembering that they aren't atomic operators in multi-threaded environments):
both of them are expressions (like i + 1
) that return a result (like i + 1
) but that have a side-effect (unlike i + 1
). The side-effect is that they increment the variable i
. The big question is "in which order everything happens?" The answer is quite simple:
- pre increment
++i
: increments i
and returns the new value of i
- post increment
i++
: increments i
and returns the old value of i
Now... The important part is that the increments i
always happens first. Then a value (the old or the new) is returned.
Let's make an example (the example of Lippert is quite complex. I'll make a different, more simple example, that isn't as much complete but that is enough to check if the order I said before is right or not) (technically I'll make two examples)
Example 1:
unchecked
{
int i = Int32.MaxValue;
Console.WriteLine("Hello! I'm trying to do my work here {0}", i++);
Console.WriteLine("Work done {1}", i);
}
Example 2:
checked
{
int i = Int32.MaxValue;
Console.WriteLine("Hello! I'm trying to do my work here {0}", i++);
Console.WriteLine("Work done {1}", i);
}
checked
means that if there is an overflow an exception (OverflowException
) will be thrown. unchecked
means that the same operation won't throw an exception. Int32.MaxValue + 1
surely will overflow. With checked
there will be an exception, with unchecked
i
will become -1.
Let's try running the first code piece. Result:
Hello! I'm trying to do my work here 2147483647
Work done -1
Ok... The i
was incremented but the Console.WriteLine
received the old value (Int32.MaxValue == 2147483647
). From this example we can't determine the order of the post-increment and of the calling of Console.WriteLine
.
Let's try running the second code piece. Result:
System.OverflowException: Arithmetic operation resulted in an overflow.
Ok... It's quite clear that first the post-increment was executed, caused an exception, and then clearly the Console.WriteLine
wasn't executed (because the program ended).
So we know that the order I said is the right one.
Now. What should you learn from this example? The same thing I learned many years ago. Pre and post increments in C and C# are good for obfuscated code contests. They aren't good for many other things (but note that C++ is different!). From that lesson I learned that there are exactly two places where you can use post-increment freely, and there are exactly zero places where you can use pre-increment freely.
"Safe" post-increment
for (int i = 0; i < x; i++)
and
i++; // Written alone. Nothing else on the same line but a comment if necessary.
"Safe" pre-increment
(nothing)