&& and || -- precedence evaluation doubt

Discussion in 'C Programming' started by Roshan Mathews, Apr 18, 2006.

  1. According to the precedence rules && has a higher precedence than
    || and both are 'left to right' associative. So in an expression
    like

    ++i || ++j && ++k

    where i, j, k are 0, -1, 0 (before the expression is evaluated),
    shouldn't the && part be evaluated before the || part? In which
    case will the evaluation be stopped short if the right side
    evaluates to 1 (true)?

    Or is the evaluation of this expression implementation dependent?

    --
    Roshan Mathews
    Dr. MGR Deemed University
    Chennai
     
    Roshan Mathews, Apr 18, 2006
    #1
    1. Advertising

  2. Roshan Mathews

    Eric Sosman Guest

    Roshan Mathews wrote On 04/18/06 11:54,:
    > According to the precedence rules && has a higher precedence than
    > || and both are 'left to right' associative. So in an expression
    > like
    >
    > ++i || ++j && ++k
    >
    > where i, j, k are 0, -1, 0 (before the expression is evaluated),
    > shouldn't the && part be evaluated before the || part? In which
    > case will the evaluation be stopped short if the right side
    > evaluates to 1 (true)?


    Precedence is not evaluation order. (Don't feel bad;
    many others have confused the two.) Precedence says that
    the expression above means the same as

    ++i || (++j && ++k) /* RIGHT */

    rather than

    (++i || ++j) && ++k /* RWONG */

    Once the meaning is determined (by precedence or by
    explicit grouping or by a combination), the evaluation
    proceeds. For this expression, ++i is evaluated first.
    Since it turns out to be non-zero (for the given values),
    the rest of the expression is not evaluated at all, and
    the result of the expression is 1.

    > Or is the evaluation of this expression implementation dependent?


    No.

    --
     
    Eric Sosman, Apr 18, 2006
    #2
    1. Advertising

  3. Roshan Mathews

    Richard Bos Guest

    "Roshan Mathews" <> wrote:

    > According to the precedence rules && has a higher precedence than
    > || and both are 'left to right' associative. So in an expression
    > like
    >
    > ++i || ++j && ++k
    >
    > where i, j, k are 0, -1, 0 (before the expression is evaluated),
    > shouldn't the && part be evaluated before the || part?


    No. This higher precendence means nothing more than that a || b && c is
    equal to a || (b && c), not to (a || b) && c. It says nothing about the
    order in which any of the operands are evaluated.
    This is just as true of * and +, or of [] and ==. [] having higher
    precedence than == means that x == y[z] does evaluate to x == (y[z]),
    not to the (nonsensical) (x == y)[z]. It does not mean that y and z are
    evaluated before x.

    There is a special case, however, for the && and || operators, which
    guarantees the opposite of your what you suppose. They are said to
    short-circuit; that is, they are required to be evaluated left-to-right,
    and when the value of the entire expression is known, that value is
    returned and no other operands are even looked at.
    This means that ++i || ++j && ++k is handled like this:

    Evaluate ++i. If this is true (non-zero), the whole expression is true
    (to be precise, it is 1); stop here.
    Ok, we now know that i used to be -1, and ++i was 0 (and since both
    || and && also introduce a sequence point, so is i, now; this is not
    important in this example, but can be in other circumstances; e.g.,
    it means that --i && a does not invoke undefined behaviour).
    Evaluate ++j. If it is zero, the sub-expression ++j && ++k is zero,
    and since ++i is also zero if we've got this far, so is the entire
    expression; if so, stop here.
    Now we know that ++i was 0 and ++j was non-zero.
    Evaluate ++k. If it's false, the expression is false (0); if it's
    true (non-zero), the expression is true (specifically 1).

    Richard
     
    Richard Bos, Apr 18, 2006
    #3
  4. Roshan Mathews wrote:
    >
    > According to the precedence rules && has a higher precedence than
    > || and both are 'left to right' associative. So in an expression
    > like
    >
    > ++i || ++j && ++k
    >
    > where i, j, k are 0, -1, 0 (before the expression is evaluated),
    > shouldn't the && part be evaluated before the || part? In which
    > case will the evaluation be stopped short if the right side
    > evaluates to 1 (true)?
    >
    > Or is the evaluation of this expression implementation dependent?


    Just because && has higher precedence than "||" doesn't mean that it
    must be executed first, merely that the entire right-side must be
    evaluated before or-ing it in. The entire boolean sequence still
    needs to be evaluated left-to-right.

    Your statement is equivalent to:

    ++i || ( ++j && ++k )

    The "++i" is evaluated first. Because "++i" is non-zero, the rest of
    the expression is not evaluated.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Apr 18, 2006
    #4
  5. Richard Bos <> wrote:

    > There is a special case, however, for the && and || operators, which
    > guarantees the opposite of your what you suppose. They are said to
    > short-circuit; that is, they are required to be evaluated left-to-right,


    Boring pedantic question: Are they required to really be evaluated
    left-to-right, or must the implementation merely behave "as-if" the
    arguments had been evaluated left-to-right?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Apr 19, 2006
    #5
  6. In article <e23v18$fqj$> Christopher Benson-Manica <> writes:
    > Richard Bos <> wrote:
    >
    > > There is a special case, however, for the && and || operators, which
    > > guarantees the opposite of your what you suppose. They are said to
    > > short-circuit; that is, they are required to be evaluated left-to-right,

    >
    > Boring pedantic question: Are they required to really be evaluated
    > left-to-right, or must the implementation merely behave "as-if" the
    > arguments had been evaluated left-to-right?


    Always as-if.
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Apr 19, 2006
    #6
  7. Christopher Benson-Manica wrote:
    > Richard Bos <> wrote:
    >
    > > There is a special case, however, for the && and || operators, which
    > > guarantees the opposite of your what you suppose. They are said to
    > > short-circuit; that is, they are required to be evaluated left-to-right,

    >
    > Boring pedantic question: Are they required to really be evaluated
    > left-to-right, or must the implementation merely behave "as-if" the
    > arguments had been evaluated left-to-right?


    There is no 'merely' about it for a conforming implementation. :)

    An implementation can replace...

    i || j++ && 0;

    ....with...

    if (!i) j++;

    However...

    i || 0 && j++;

    ....must be a no-op (assuming i is not volatile.)

    the more classic case is something like...

    if (p && *p)

    Search for Chris Torek's posts on how an implementation can
    'silently' trap by dereferencing a potential null pointer in parallel
    to the null test, but it must 'cope' with that trapping and behave
    as if it worked correctly.

    There are circumstances involving volatile objects where a practical
    conforming implementation must still be very careful about how it
    handles the evaluation order of certain expressions.

    --
    Peter
     
    Peter Nilsson, Apr 19, 2006
    #7
  8. Roshan Mathews

    Richard Bos Guest

    Christopher Benson-Manica <> wrote:

    > Richard Bos <> wrote:
    >
    > > There is a special case, however, for the && and || operators, which
    > > guarantees the opposite of your what you suppose. They are said to
    > > short-circuit; that is, they are required to be evaluated left-to-right,

    >
    > Boring pedantic question: Are they required to really be evaluated
    > left-to-right, or must the implementation merely behave "as-if" the
    > arguments had been evaluated left-to-right?


    Well, of course, everything is as-if. However, that as-if had also
    better involve not reading any volatiles, not calling rand(), not
    causing any FP exceptions, and so on, and so forth. Your program really
    must not be able to tell the difference in any reliable way. (Difference
    in execution time, for example, does not count as reliable.)

    Richard
     
    Richard Bos, Apr 19, 2006
    #8
  9. Roshan Mathews

    Al Balmer Guest

    On Wed, 19 Apr 2006 00:08:08 +0000 (UTC), Christopher Benson-Manica
    <> wrote:

    >Richard Bos <> wrote:
    >
    >> There is a special case, however, for the && and || operators, which
    >> guarantees the opposite of your what you suppose. They are said to
    >> short-circuit; that is, they are required to be evaluated left-to-right,

    >
    >Boring pedantic question: Are they required to really be evaluated
    >left-to-right, or must the implementation merely behave "as-if" the
    >arguments had been evaluated left-to-right?
    >

    It's required that you not know or care ;-)

    --
    Al Balmer
    Sun City, AZ
     
    Al Balmer, Apr 19, 2006
    #9
    1. Advertising

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. Christos TZOTZIOY Georgiou

    Introspection: expression evaluation order - precedence

    Christos TZOTZIOY Georgiou, Oct 24, 2003, in forum: Python
    Replies:
    0
    Views:
    318
    Christos TZOTZIOY Georgiou
    Oct 24, 2003
  2. Replies:
    26
    Views:
    681
    Mark McIntyre
    Jun 15, 2007
  3. Replies:
    22
    Views:
    745
    Old Wolf
    Aug 28, 2007
  4. vjay
    Replies:
    7
    Views:
    388
    Robin Kåveland Hansen
    Nov 27, 2007
  5. Seebs
    Replies:
    2
    Views:
    172
    Seebs
    Nov 22, 2009
Loading...

Share This Page