Order of evaluation

Discussion in 'C++' started by publictom@blueyonder.co.uk, May 20, 2005.

  1. Guest

    Is the following statement true?

    "It is required that the operands to an operator be fully evaluated
    before the operator itself is evaluated."

    The only way I can think of that it would be practically possible to
    violate this would be for subexpression like a += b to return its value
    (a + b) for use in the parent expression, but leave it until some time
    later before it assigned that value to a. Is this allowed?

    If this statement above is true, then the following is defined:

    int a = /*something*/, b = /*something else*/;
    a ^= b ^= a ^= b;

    A couple of people at this page:
    http://c2.com/cgi/wiki?ThreeStarProgrammer, have said that the above
    expression is undefined because it modifies 'a' twice without an
    intervening sequence point. If operands have to be fully evaluated
    before the operator can be evaluated, this is not undefined though,
    because it is equivalent to (a ^= (b ^= (a ^= b))), in which each
    operator with side-effects depends on the result of the next. Is it
    undefined or not?

    ps. Clearly the order of evaluation of the subexpressions in (a ^= b)
    ^= (a ^= b) is undefined - I'm certainly not disagreeing with that.

    pps. If a and b were of a user-defined type, the ^= operator would be a
    function call, and the parameters to a function call have to be
    evaluated before the call, so in this case it would be defined.
     
    , May 20, 2005
    #1
    1. Advertisements

  2. wrote:
    > Is the following statement true?
    >
    > "It is required that the operands to an operator be fully evaluated
    > before the operator itself is evaluated."


    Yes.

    > The only way I can think of that it would be practically possible to
    > violate this would be for subexpression like a += b to return its value
    > (a + b) for use in the parent expression, but leave it until some time
    > later before it assigned that value to a. Is this allowed?


    Yes, and it sometimes causes trouble if 'a' is changed twice before the
    next sequence point.

    > If this statement above is true, then the following is defined:
    >
    > int a = /*something*/, b = /*something else*/;
    > a ^= b ^= a ^= b;


    Nope. This expression changes the value of 'a' and 'b' twice between the
    sequence points.

    > A couple of people at this page:
    > http://c2.com/cgi/wiki?ThreeStarProgrammer, have said that the above
    > expression is undefined because it modifies 'a' twice without an
    > intervening sequence point. If operands have to be fully evaluated
    > before the operator can be evaluated, this is not undefined though,
    > because it is equivalent to (a ^= (b ^= (a ^= b))), in which each
    > operator with side-effects depends on the result of the next. Is it
    > undefined or not?


    It is undefined. Evaluation of operands (obtaining the values) and side
    effects taking place are two different things.

    > ps. Clearly the order of evaluation of the subexpressions in (a ^= b)
    > ^= (a ^= b) is undefined - I'm certainly not disagreeing with that.
    >
    > pps. If a and b were of a user-defined type, the ^= operator would be a
    > function call, and the parameters to a function call have to be
    > evaluated before the call, so in this case it would be defined.


    Yes.

    V
     
    Victor Bazarov, May 20, 2005
    #2
    1. Advertisements

  3. Guest

    > ... Evaluation of operands (obtaining the values) and side
    >effects taking place are two different things.


    It all comes clear to me now. Thanks very much for your help.
     
    , May 20, 2005
    #3
  4. Guest

    Just to make sure I've got this straight:
    int a = 1, b = 2, c = 3;
    (a = b) = c;
    This is undefined too, isn't it? 'a' could end up containing either 2
    or 3 as there are no sequence points between the two assignments.

    Thanks,
    Tom
     
    , May 20, 2005
    #4
  5. wrote:
    > Just to make sure I've got this straight:
    > int a = 1, b = 2, c = 3;
    > (a = b) = c;
    > This is undefined too, isn't it? 'a' could end up containing either 2
    > or 3 as there are no sequence points between the two assignments.


    That is a good question. Let me start the explanation by saying that
    you're *incorrect* using the word "either" here. _If_ the behaviour is
    undefined, *anything* can happen.

    Now, to the actual thing. I have read the Standard (again) and can only
    say that it's ambiguous at best. The exact text is "The result of the
    assignment operation is the value stored in the left operand after the
    assignment has taken place; the result is an lvalue." How should we
    understand this? Maybe my bad English plays tricks on me, but I read
    that sentence as dual in meaning. OOH, it can mean, "The result of the
    assignment operation is only known after assignment is complete (and the
    value is stored)". OTOH, it can mean, "The result of the assignment
    operation is _the same_ as what _will be stored_ when the sequence point
    is reached". If it's the former, then both expressions (the one you asked
    about before and the one you're asking about here) are well-defined, since
    assignment always takes place before the lvalue is returned. If it is the
    latter that is true, then both forms are undefined.

    I believe the safer would be interpret it as the latter. I am now unsure,
    though, which one is the correct interpretation.

    V
     
    Victor Bazarov, May 20, 2005
    #5
  6. Guest

    That is confusing, indeed. It is good advice to assume it is unsafe and
    just avoid such things. I'm getting the feeling I should get a copy of
    the standard, as well.
    Thanks again for your help. Your English doesn't seem bad at all.
    Tom
     
    , May 20, 2005
    #6
  7. Joe Gottman Guest

    <> wrote in message
    news:...
    > Is the following statement true?
    >
    > "It is required that the operands to an operator be fully evaluated
    > before the operator itself is evaluated."
    >


    It is true in all except two cases: a && b and a || b. In the first case,
    if a evaluates to false then a &&b must be false whatever the value of b is.
    Similarly, in the second case if a evaluates to true then a || b must be
    true whatever b is. In both these cases, the operator immediately returns
    the correct value after the first operand is evaluated, and the second one
    isn't evaluated at all. This is called "short-circuit evaluation".

    Joe Gottman
     
    Joe Gottman, May 21, 2005
    #7
  8. Pete Becker Guest

    Joe Gottman wrote:
    >
    > It is true in all except two cases: a && b and a || b.


    The ternary operator is also an exception.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 21, 2005
    #8
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nan Li

    evaluation order

    Nan Li, Nov 14, 2005, in forum: Java
    Replies:
    11
    Views:
    692
    Oliver Wong
    Nov 15, 2005
  2. Xavier Decoret

    Evaluation order for a=b

    Xavier Decoret, Jul 3, 2003, in forum: C++
    Replies:
    1
    Views:
    365
    Ron Natalie
    Jul 3, 2003
  3. Ilias Lazaridis
    Replies:
    2
    Views:
    418
    Ilias Lazaridis
    Apr 24, 2005
  4. Ilias Lazaridis
    Replies:
    74
    Views:
    859
    Ilias Lazaridis
    Apr 4, 2005
  5. Ilias Lazaridis
    Replies:
    18
    Views:
    392
    Bill Guindon
    Apr 9, 2005
Loading...

Share This Page