AND and OR and parentheses

Discussion in 'C Programming' started by rick, Aug 15, 2005.

  1. rick

    rick Guest

    the following line appears in the K&R book in section 5.7:
    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    my compiler suggests parentheses "around && within ||"

    given that the AND operator has higher precedence than OR, would the
    correct grouping be this:
    leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    ?

    thanks,
    ~rick
     
    rick, Aug 15, 2005
    #1
    1. Advertising

  2. rick wrote:

    > the following line appears in the K&R book in section 5.7:
    > leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    > my compiler suggests parentheses "around && within ||"


    I hate that warning. Some compilers can be very fussy, even if the
    precedence is obvious.

    > given that the AND operator has higher precedence than OR, would the
    > correct grouping be this:
    > leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    > ?


    Yes.

    > thanks,
    > ~rick


    Peter
     
    Peter Pichler, Aug 15, 2005
    #2
    1. Advertising

  3. rick

    Eric Sosman Guest

    rick wrote:
    > the following line appears in the K&R book in section 5.7:
    > leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    > my compiler suggests parentheses "around && within ||"
    >
    > given that the AND operator has higher precedence than OR, would the
    > correct grouping be this:
    > leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    > ?


    Yes; your parentheses don't change the meaning of the
    original. The compiler (presumably) issues the warning
    because the people who wrote it felt that this is something
    programmers often get wrong.

    Oddly enough, in this particular case you *can't* get
    it wrong! Consider the other possibility:

    leap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);

    This expression gives the same value to `leap' as the first
    (equivalent) pair, even though it arrives at the value by a
    different route.

    --
     
    Eric Sosman, Aug 15, 2005
    #3
  4. rick

    CBFalconer Guest

    Eric Sosman wrote:
    > rick wrote:
    >
    >> the following line appears in the K&R book in section 5.7:
    >> leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    >> my compiler suggests parentheses "around && within ||"
    >>
    >> given that the AND operator has higher precedence than OR, would
    >> the correct grouping be this:
    >> leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

    >
    > Yes; your parentheses don't change the meaning of the
    > original. The compiler (presumably) issues the warning
    > because the people who wrote it felt that this is something
    > programmers often get wrong.
    >
    > Oddly enough, in this particular case you *can't* get
    > it wrong! Consider the other possibility:
    >
    > leap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
    >
    > This expression gives the same value to `leap' as the first
    > (equivalent) pair, even though it arrives at the value by a
    > different route.


    Actually that last is probably the most efficient, since 75% of the
    time the value is resolved with one test, 24% with two tests, and
    1% with three. I would use even more parens, as in:

    leap = (year % 4 == 0) &&
    ((year % 100 != 0) || (year % 400 == 0));

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Aug 15, 2005
    #4
  5. rick

    akarl Guest

    CBFalconer wrote:
    > Eric Sosman wrote:
    >
    >>rick wrote:
    >>
    >>
    >>>the following line appears in the K&R book in section 5.7:
    >>> leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    >>>my compiler suggests parentheses "around && within ||"
    >>>
    >>>given that the AND operator has higher precedence than OR, would
    >>>the correct grouping be this:
    >>> leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

    >>
    >> Yes; your parentheses don't change the meaning of the
    >>original. The compiler (presumably) issues the warning
    >>because the people who wrote it felt that this is something
    >>programmers often get wrong.
    >>
    >> Oddly enough, in this particular case you *can't* get
    >>it wrong! Consider the other possibility:
    >>
    >> leap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
    >>
    >>This expression gives the same value to `leap' as the first
    >>(equivalent) pair, even though it arrives at the value by a
    >>different route.

    >
    >
    > Actually that last is probably the most efficient, since 75% of the
    > time the value is resolved with one test, 24% with two tests, and
    > 1% with three. I would use even more parens, as in:
    >
    > leap = (year % 4 == 0) &&
    > ((year % 100 != 0) || (year % 400 == 0));
    >


    Yes, I think parentheses around the "boolean" (atomic) expressions
    improve readability considerably, it's also customary in mathematics.
    (However, I think relying on the precedence of `and' over `or' is
    perfectly okay.)

    August
     
    akarl, Aug 17, 2005
    #5
  6. rick

    Malcolm Guest

    "akarl" <> wrote
    >
    > Yes, I think parentheses around the "boolean" (atomic) expressions improve
    > readability considerably, it's also customary in mathematics. (However, I
    > think relying on the precedence of `and' over `or' is perfectly okay.)
    >

    The rule I use is that you can rely on your reader to know that * and / have
    a higher precedence than + and -, and everything else needs parentheses.
     
    Malcolm, Aug 17, 2005
    #6
  7. rick

    Richard Bos Guest

    "Malcolm" <> wrote:

    > "akarl" <> wrote
    > >
    > > Yes, I think parentheses around the "boolean" (atomic) expressions improve
    > > readability considerably, it's also customary in mathematics. (However, I
    > > think relying on the precedence of `and' over `or' is perfectly okay.)
    > >

    > The rule I use is that you can rely on your reader to know that * and / have
    > a higher precedence than + and -, and everything else needs parentheses.


    Are you sure?

    #include <stdio.h>

    int main(void)
    {
    int i, j;

    for ((i=1); (i<10); (i++)) {
    (j=(i*10+3));
    (printf(("Value nr. %d is %d\n"), (i), (j)));
    }
    }

    Richard
     
    Richard Bos, Aug 17, 2005
    #7
  8. rick

    Netocrat Guest

    On Wed, 17 Aug 2005 06:38:50 +0000, Richard Bos wrote:

    > "Malcolm" <> wrote:
    >
    >> "akarl" <> wrote
    >> >
    >> > Yes, I think parentheses around the "boolean" (atomic) expressions improve
    >> > readability considerably, it's also customary in mathematics. (However, I
    >> > think relying on the precedence of `and' over `or' is perfectly okay.)
    >> >

    >> The rule I use is that you can rely on your reader to know that * and / have
    >> a higher precedence than + and -, and everything else needs parentheses.

    >
    > Are you sure?
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > int i, j;
    >
    > for ((i=1); (i<10); (i++)) {
    > (j=(i*10+3));
    > (printf(("Value nr. %d is %d\n"), (i), (j)));
    > }
    > }


    Well if we're going to take Malcolm's statement literally without applying
    common sense, this would be even better (we could go indefinitely further):

    #include <stdio.h>

    int main(void)
    {
    int i, j;

    for ((((i=1))); (((i<10))); (((i++)))) {
    (((j=(((i*10+3))))));
    (((printf(((("Value nr. %d is %d\n"))), (((i))), (((j)))))));
    }
    }

    I think that both of these fail to capture his intent.

    --
    http://members.dodo.com.au/~netocrat
     
    Netocrat, Aug 17, 2005
    #8
  9. rick

    Netocrat Guest

    On Wed, 17 Aug 2005 02:44:53 -0700, Suman wrote:
    > Netocrat wrote:
    >> On Wed, 17 Aug 2005 06:38:50 +0000, Richard Bos wrote:
    >> > "Malcolm" <> wrote:
    >> >> "akarl" <> wrote
    >> >> >
    >> >> > Yes, I think parentheses around the "boolean" (atomic) expressions
    >> >> > improve readability considerably, it's also customary in
    >> >> > mathematics. (However, I think relying on the precedence of `and'
    >> >> > over `or' is perfectly okay.)
    >> >> >
    >> >> The rule I use is that you can rely on your reader to know that *
    >> >> and / have a higher precedence than + and -, and everything else
    >> >> needs parentheses.

    >
    > He m[i/e]ssed up with the last part of the sentence. Here it is for your
    > viewing pleasure:
    >
    > With the usual exceptions, of course.


    Yes, obviously that's what Malcolm meant and he shouldn't be required to
    write it (which he didn't according to my newsfeed).

    > [snipped a lot of code from fertile minds]
    >
    > C'mon guys -- be a sport.


    I thought I was being - the point of my post was that the literal and
    strict interpretation of what was clearly a helpful guideline rather than
    a formal rule was lacking in common sense and obviously wasn't what was
    intended. Hence the first line of my post: "if we're going to [not apply]
    common sense" and the final line:

    > I think that both of these fail to capture his intent.


    --
    http://members.dodo.com.au/~netocrat
     
    Netocrat, Aug 17, 2005
    #9
  10. rick

    Suman Guest

    Netocrat wrote:
    > On Wed, 17 Aug 2005 06:38:50 +0000, Richard Bos wrote:
    >
    > > "Malcolm" <> wrote:
    > >
    > >> "akarl" <> wrote
    > >> >
    > >> > Yes, I think parentheses around the "boolean" (atomic) expressions improve
    > >> > readability considerably, it's also customary in mathematics. (However, I
    > >> > think relying on the precedence of `and' over `or' is perfectly okay.)
    > >> >
    > >> The rule I use is that you can rely on your reader to know that * and / have
    > >> a higher precedence than + and -, and everything else needs parentheses.


    He m[i/e]ssed up with the last part of the sentence. Here it is for
    your
    viewing pleasure:

    With the usual exceptions, of course.

    [snipped a lot of code from fertile minds]

    C'mon guys -- be a sport.
     
    Suman, Aug 17, 2005
    #10
  11. rick

    Richard Bos Guest

    Netocrat <> wrote:

    > On Wed, 17 Aug 2005 06:38:50 +0000, Richard Bos wrote:
    >
    > > "Malcolm" <> wrote:
    > >
    > >> The rule I use is that you can rely on your reader to know that * and / have
    > >> a higher precedence than + and -, and everything else needs parentheses.

    > >
    > > Are you sure?
    > >
    > > #include <stdio.h>
    > >
    > > int main(void)
    > > {
    > > int i, j;
    > >
    > > for ((i=1); (i<10); (i++)) {
    > > (j=(i*10+3));
    > > (printf(("Value nr. %d is %d\n"), (i), (j)));
    > > }
    > > }

    >
    > Well if we're going to take Malcolm's statement literally without applying
    > common sense,


    My point was that, as he phrased it, Malcolm's statement doesn't really
    allow common sense. Yes, my example of putting parens around a whole
    assignment statement is a bit over the top; but I doubt that, in writing
    "everything else", Malcolm had thought about = , ?: sizeof and so forth.
    In fact, I'd say that he thought about | & ^ || && == != < > and that's
    probably about it.

    Richard
     
    Richard Bos, Aug 19, 2005
    #11
  12. rick

    Malcolm Guest

    "Richard Bos" <> wrote
    >> >> The rule I use is that you can rely on your reader to know that * and
    >> >> / have
    >> >> a higher precedence than + and -, and everything else needs
    >> >> parentheses.
    >> >

    > My point was that, as he phrased it, Malcolm's statement doesn't really
    > allow common sense. Yes, my example of putting parens around a whole
    > assignment statement is a bit over the top; but I doubt that, in writing
    > "everything else", Malcolm had thought about = , ?: sizeof and so forth.
    > In fact, I'd say that he thought about | & ^ || && == != < > and that's
    > probably about it.
    >

    The other rule, which is just as important, is that the reader can't be
    expected to cope with more than three layers of nesting. Unfortunately this
    makes the "parenthese round everything ambiguous" rule hard to follow.

    Personally I always give parenthese to sizeof() to make it look like a
    function call, but I don't obvious write (sizeof(x)) which a literal
    interpretation would demand.

    The ++ operator is quirky because precedence and order of evaluation is the
    same. It is so idiomatic that you have to use it in compound expressions,
    though I prefer to put it on a line of its own where possible.
     
    Malcolm, Aug 20, 2005
    #12
  13. rick

    pete Guest

    Malcolm wrote:

    > Personally I always give parenthese to sizeof()
    > to make it look like a function call,


    I avoid giving parentheses to sizeof,
    because I don't want a constant expression
    to look like a function call.

    --
    pete
     
    pete, Aug 20, 2005
    #13
  14. rick

    Joe Wright Guest

    Malcolm wrote:
    > "Richard Bos" <> wrote
    >
    >>>>>The rule I use is that you can rely on your reader to know that * and
    >>>>>/ have
    >>>>>a higher precedence than + and -, and everything else needs
    >>>>>parentheses.
    >>>>

    >>My point was that, as he phrased it, Malcolm's statement doesn't really
    >>allow common sense. Yes, my example of putting parens around a whole
    >>assignment statement is a bit over the top; but I doubt that, in writing
    >>"everything else", Malcolm had thought about = , ?: sizeof and so forth.
    >>In fact, I'd say that he thought about | & ^ || && == != < > and that's
    >>probably about it.
    >>

    >
    > The other rule, which is just as important, is that the reader can't be
    > expected to cope with more than three layers of nesting. Unfortunately this
    > makes the "parenthese round everything ambiguous" rule hard to follow.
    >

    Who made this rule? There is nothing magic about three nesting levels.

    > Personally I always give parenthese to sizeof() to make it look like a
    > function call, but I don't obvious write (sizeof(x)) which a literal
    > interpretation would demand.
    >

    Why? It is not a function. If the argument needs parentheses I insert a
    space 'sizeof (int)' so that it doesn't look like a function.

    > The ++ operator is quirky because precedence and order of evaluation is the
    > same. It is so idiomatic that you have to use it in compound expressions,
    > though I prefer to put it on a line of its own where possible.
    >

    What is 'quirky' about it? Sharing precedence level with sizeof is a
    problem how?

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Aug 20, 2005
    #14
    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. =?Utf-8?B?UGF0cmljay5PLklnZQ==?=

    'AddressOf' operand must be the name of a method; no parentheses a

    =?Utf-8?B?UGF0cmljay5PLklnZQ==?=, Oct 18, 2004, in forum: ASP .Net
    Replies:
    15
    Views:
    7,564
    =?Utf-8?B?UGF0cmljay5PLklnZQ==?=
    Oct 19, 2004
  2. C parentheses, brackets and brace

    , Jun 15, 2007, in forum: C Programming
    Replies:
    8
    Views:
    883
    CBFalconer
    Jun 16, 2007
  3. spasmous

    Parentheses and compiler optimzation

    spasmous, Apr 10, 2008, in forum: C Programming
    Replies:
    15
    Views:
    473
    Anonymous
    Apr 13, 2008
  4. jsnark

    parentheses and newlines

    jsnark, Feb 17, 2012, in forum: Ruby
    Replies:
    2
    Views:
    570
    Simon Krahnke
    Feb 18, 2012
  5. Addy
    Replies:
    2
    Views:
    112
    Anno Siegel
    Aug 26, 2003
Loading...

Share This Page