Ahmed El-Halwagy’s Blog

Archive for August 2009

In my last post when I linked
to a very interesting article on Eric Lippert’s blog.
Now I want to follow up on the subject of the post increment (++) operator.

Personally I used to think the the post increment operator will increment the value of its operand at the very end of the current
statement (i.e. just before the terminating “;”). So according to my understanding, this expression (x+(y++)+y) would evaluate to 0–
of course of both x and y were initialized to 0.

If you tried this example in the C# compiler you would find that the result of
the expression is 1! (yes not 0 :S). Obviously I was wrong! Here’s how I thought the sequence of evaluating this expression (z = x+(y++)+y;)
would go: First, x is added to y and the result is stored somewhere (a for example)
Second, the result of (#First) will be added to y again (note: y here is still 0, the increment didn’t happen yet)
and the result of this evaluation is stored somewhere (b for example)
Third, the assignment will happen; assigning the result of (#second “b”) to whatever on the left side of the “=” operator.
Fourth: Now (and only now) increment y. y = 1 now.

If this is right, I would get 0 as a result of Console.WriteLine(z); but it is NOT. This flow of evaluation is not correct.
My understanding of the
post increment operator is not right! (I’m doomed, eh!?).

So I checked up the c# documentation, still couldn’t find any specific statement
about when exactly the increment happens. After an hour on the internet, I turned to my favorite site, my
third place
now, Stackoverflow.com.

I logged in and posted a question.
Go ahead click the link and check the accepted answer, if you’re lazy, here’s my summary of the answer.

First you have to know that the ++ operator has an operation to perform with a specified precedence and a SIDE EFFECT. In short, the ++
operator has the higher precednce than (* + – /). See the specs
This means that the operator will execute instantly! Yes Instantly! So the increment will be the first thing to happen (even if it’s
post increment or pre-increment). The difference between pre and post comes from the side effect. When post incrementing the old value is
stored, then the increment happens (i.e. the value of the variable increments),
and the value that’s used to continue evaluating the expression is the (yeah, you guessed it) old value.

So to get back to the example (z = z +(y++) +y;), the order of evaluating this expression would be as follows:

  1. Store the value of y somwhere -say a. a now = 0.
  2. Increment y (remember the increment has the highest precednece).
  3. Add x to the value of a(which is the old value of y; that’s the side effect part of the operator) and save the result of
    the addition somewhere (say b). now b = 0;
  4. Add the value of b to the value of y (what’s the value of y now? yes you’re right, it’s 1), and store the result somewhere
    say c. say now = 1.
  5. Assign the value of c to z. z now = 1.

As you can see, the increment happens instantly. And its side effect forces the use of the old value of the incremented variable
for evaluating the very next part of the expression. After that when trying to dereference the incremented value and get its value,
you will actually get the incremented value.


Makes perfect sense to me now. What about you dear reader?

Advertisements

A little ago Eric Lippert took a stand to the programming myths that people have about c#. Starting by his awesome The stack is an implementation detail
then Not everything derives from object and today’s Precedence vs Order, Redux. I have to say it was an awesome job, very nice articles -just like everything Eric writes. I strongly recommend that you scan through these articles, a lot of mysteries to be unveiled there. I’m not going to repeat what Eric said because I’m too proud to do! Well, not really! It’s just I’m not as good as Eric to think of providing new versions of his articles (what new would these new versions have anyway?) I just want to stop by the last article Precedence vs Order, Redux. I had a nice 12 parts conversation on facebook with one of my friends. At first I posted a Twitter post with a question and a link to Eric’s article. I got a comment from one of my friends –who stands to be one of the very best students at Century 21, IBM. The man’s comment was “value = 1”. Nice and easy! Well, that wasn’t what I expected from this friend -I know the answer, I run the sample code, and seen the value of value :), and I read Eric’s article. What I expected him to say is 0. Because as far as I know, this program should work this way:

1- Get the value of arr[0] .. the inner expression arr[0] .. 0 returned

2- Get the value of arr[0] again .. the outer arr[arr[0]] .. still 0 returned

3- Now assign the value of 0 to the variable value.

4- Now and not before now, Increment arr[0].

Apparently what I know is wrong. The increment didn’t happen the moment I expected it to happen –after assigning the value. Actually it happened before assigning the value. Frankly I don’t understand why!? I tried to search the C# spec and couldn’t find anything to state strictly when the increment should happen in case of post increment and pre-increment.
Another interesting and confusing case is a snippet I saw in a comment by Peter Ibboston on the same article by Eric:

The one that confused me is this C# code which gives different results in C & C#

int[] data={11,22,33};int i=1;data[i++]=data[i]+5;

I couldn’t find a bit in the C# spec that said anything about when increment should happen. I had presumed that the rvalue would be evaluated first followed by the lvalue.

Any ideas where I missed it.

To finalize I would say, there’s no documentation to specifically tell when the increment will happen –AFAIK of course. Eric emphasized an interesting statement in his article too, he said:

I emphasize that the logical sequence is well-defined because the compiler, jitter and processor are all allowed to change the actual order of events for optimization purposes, subject to the restriction that the optimized result must be indistinguishable from the required result in single-threaded scenarios.

The compiler or the Jitter or the processor are all able to modify the logical sequence for optimization purposes. The optimization shouldn’t affect the output in a single-threaded application, however, in a multi-threaded app, it might be observable. Yeah I see. I still don’t know why is this working this way? When exactly the increment is happening?

What do you think dear reader?

Please help me clarify the facts, and eliminate these confusions.


Calendar

August 2009
S M T W T F S
« Jul   Nov »
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Categories

Delicious

Recent Twitter Updates