Poser update


A few updates on the results of my “poser” post.


First, anybody who said “anybody who coded that deserves whatever they get” is absolutely correct, but gets no points because that wasn’t the answer we were looking for.


I thought it was an interesting question for two reasons (most of which Wes covered in his response, but you may not have read it).


First, when you write:


x += 5;


the compiler write this as


x = x + 5;


which obviously changes the order of evaluation, and the answer to the question.


The second is that C# evaluates from left to right, so you can reason about how expressions are evaluated.


In C++, it’s implementation-defined, and you truly get what you deserve.

Comments (12)

  1. Wes says:

    Did you mean "The second is that C# evaluates from left to right" ?

  2. Eric says:

    Thanks, Wes

  3. Jiho Han says:

    I have some questions regarding the posers.

    In the second question, do the parens do anything to change the eval order? My guess is no. If I am incorrect, can you show me?

    Also, I am a little confused as to when the post increment operator gets executed. I always thought that it was after all processing in the current statement.

    Then in something like the following:

    z = 2;

    (1) z = z + z++;

    (2) z = z * z++;

    (3) z = z + (z++);

    (4) z = z * (z++);

    What would z contain for each (z=2 as the initial condition)?

    My answers would be 4, 4, 5, 6?

    Could you explain so that I can confirm my understanding?

    Thanks you guys.

  4. Kael Rowan says:

    Jiho, z will result in 4 each time because C# seems to evaluate identifiers and their prefix/postfix operators from left to right regardless of how operator precedence determines they should be combined.

    I would expect 4, 4, 5, 6 as well from interpreting the C# spec. After having a long explaination from Wes in the previous blog I’ve been convinced that operator precedence doesn’t necessarily control the order of identifer evaluation and the corresponding perfix/postfix operators.

    Eric, can you explain or give us a link to how C# relates precedence to actual evaluation?

    -Kael

  5. James Curran says:

    >>In C++, it’s implementation-defined

    Correction: In C++, it is UNDEFINED.

    "implementation-defined" covers such things as "sizeof(int)" which are legal but different on different machines.

    "Undefined" means is illegal everywhere.

  6. Joshua says:

    Will someone define what exactly "implementation-defined" means?

  7. Jason G says:

    I could tell you what "implementation defined" means on this blog, but it might be different on Raymond Chen’s.

  8. Ron says:

    I agree with Kael. (3) and (4) seem at odds with 7.2.1 of the C# specification (specifically the last paragraph). I’d even go so far as to say it’s a bug in the C# compiler.

    Any insight to describe why this behavior is (though I suspect the parens may be "optimized" out at compile time) would be appreciated.

  9. Eric Gunnerson says:

    Parens are meaningful, but not for binary operators.

    I think the notion that taking:

    z++

    and writit it as:

    (z++)

    would convert it to

    ++z

    would be a fairly surprising bit of behavior. If you want ++z, why not just write ++z?

  10. Kael Rowan says:

    I would never expect that (z++) would evaluate to ++z. Just because the increment may happen first, doesn’t mean that the result of the expression would change. If z = 2 then (z++) would return 2 just as z++ would; the only difference with the parens would be that the operation would happen before any further evaluations of z.

    An explanation in detail is in a feedback to your original poser post: http://blogs.msdn.com/ericgu/archive/2004/04/19/116265.aspx#116801

  11. James Curran says:

    Jason:

    From the C++ Standard:

    1.3.5 implementation defined behavior

    behavior, for a wellformed

    program construct and correct data, that depends on the implementation and

    that each implementation shall document.

    1.3.12 undefined behavior

    behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this

    International Standard imposes no requirements. Undefined behavior may also be expected when this

    International Standard omits the description of any explicit definition of behavior. [Note: permissible undefined

    behavior ranges from ignoring the situation completely with unpredictable results, to behaving during

    translation or program execution in a documented manner characteristic of the environment (with or without

    the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a

    diagnostic message).