Thursday, January 08, 2009

i=i++ - The trials and tribulations of the C incrementer

Here is a point raised by Tudor, from the infamous Romanian blog Incidentally, he does some teaching in the Java field and is a good web designer and PHP programmer.

Ok, some of you know those informatics teachers that start talking about a programming language by giving you a silly problem that would never occur in real life or by asking you to "decypher" a piece of code that looks unusable in any scenario. But bare with me and try to think this through before you read on in the post.
Question: what is the value of i (initially 0) after the following operations in C#?
  • i = i++
  • i = Math.Pow(i++,2)
  • some method that ends in return i++

First, let's think about the meaning of this ++ arcane symbol. It means increment a number, or add 1 to it. In C based languages, you can use it either after or before a variable, thus changing meaning to add 1 to i after or before assignment. As MSDN says: "The increment operator (++) increments its operand by 1. The increment operator can appear before or after its operand:
++ var
var ++
The first form is a prefix increment operation. The result of the operation is the value of the operand after it has been incremented.
The second form is a postfix increment operation. The result of the operation is the value of the operand before it has been incremented."

Now the answer is pretty clear: i will be zero after any of the operations described above. But why?! Let's examine them a little.

The first makes no sense in real world, but you could easily imagine something like i=j++ that could be used somewhere and that makes sense to set i to the original value of j, then increment j. But then doesn't it mean that i should be 1 because it gets incremented after the assignment? Well I think it should, as the last operation, but what I think happends is that the value for i gets pushed in a stack, then retrieved at the end of the sentence like this:
  i = i
push 0 to stack as the value of i
push 1 to stack as the value of i
pop value of i from stack (1)
pop value of i from stack (0)

Ok, ok, I guess that makes some sort of sense, but what about that int F(int i) { return i++; } thing? Shouldn't it increment i after the operation then return it? Apparently not. The method returns the value of i and aborts the pending increment operation.

According to Tudor, PHP would return 1 in these situations, although most C implementations, including javascript, return 0. Update: he later posted a comment retracting that statement. He also suggested it would be hard to debug something like this in case it happends. Ha! My beautiful ReSharper Visual Studio addon immediately added a wiggly line under i and said value assigned is not used in any execution path. ReSharper - Computer teachers : 1-0 ! :)


Tudor said...

This happens also in PHP...My first assumption proved to be false