Monday 15 July 2019

c# - For i = 0, why is (i += i++) equal to 0?



Take the following code (usable as a Console Application):




static void Main(string[] args)
{
int i = 0;
i += i++;
Console.WriteLine(i);
Console.ReadLine();
}


The result of i is 0. I expected 2 (as some of my colleagues did). Probably the compiler creates some sort of structure that results in i being zero.




The reason I expected 2 is that, in my line of thought, the right hand statement would be evaluated first, incrementing i with 1. Than it is added to i. Since i is already 1, it is adding 1 to 1. So 1 + 1 = 2. Obviously this is not what's happening.



Can you explain what the compiler does or what happens at runtime? Why is the result zero?



Some-sort-of-disclaimer: I'm absolutely aware you won't (and probably shouldn't) use this code. I know I never will. Nevertheless, I find it is interesting to know why it acts in such a way and what is happening exactly.


Answer



This:



int i = 0;

i += i++


Can be seen as you doing (the following is a gross oversimplification):



int i = 0;
i = i + i; // i=0 because the ++ is a postfix operator and hasn't been executed
i + 1; // Note that you are discarding the calculation result



What actually happens is more involved than that - take a look at MSDN, 7.5.9 Postfix increment and decrement operators:




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 selected operator is invoked with the saved value of x as its argument.

    • The value returned by the operator is stored in the location given by the evaluation of x.

    • The saved value of x becomes the result of the operation.





Note that due to order of precedence, the postfix ++ occurs before +=, but the result ends up being unused (as the previous value of i is used).







A more thorough decomposition of i += i++ to the parts it is made of requires one to know that both += and ++ are not atomic (that is, neither one is a single operation), even if they look like they are. The way these are implemented involve temporary variables, copies of i before the operations take place - one for each operation. (I will use the names iAdd and iAssign for the temporary variables used for ++ and += respectively).



So, a closer approximation to what is happening would be:



int i = 0;
int iAdd = i; // Copy of the current value of i, for ++
int iAssign = i; // Copy of the current value of i, for +=


i = i + 1; // i++ - Happens before += due to order of precedence
i = iAdd + iAssign;

No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...