AND and OR and parentheses

R

rick

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
 
P

Peter Pichler

rick said:
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
 
E

Eric Sosman

rick said:
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.
 
C

CBFalconer

Eric said:
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));
 
A

akarl

CBFalconer said:
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
 
M

Malcolm

akarl said:
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.
 
R

Richard Bos

Malcolm said:
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
 
N

Netocrat

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.
 
N

Netocrat

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:
 
S

Suman

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.
 
R

Richard Bos

Netocrat said:
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
 
M

Malcolm

Richard Bos said:
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.
 
P

pete

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.
 
J

Joe Wright

Malcolm said:
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?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top