I have a doubt

I

ivan

hi all,

if I have:

if(A && B || C)

which operation gets executed first?
If I remeber well should be &&, am I correct?

thanks
Ivan
 
R

Richard Heathfield

ivan said:
hi all,

if I have:

if(A && B || C)

which operation gets executed first?

See pages 21 and 53 of K&R2. Page 21 for a detailed answer to your question,
and page 53 for a more generic answer.
 
I

ivan

Martin Ambuhl said:
A is evaluated first.


Not until A is evaluated.

sorry but i do not have a C book at hand.

what I am saing is:

A && B || C

is the same as:

(A&&B)||C

or the same as:

A&&(B||C)
 
J

jaysome

hi all,

if I have:

if(A && B || C)

which operation gets executed first?
If I remeber well should be &&, am I correct?

thanks
Ivan

Assuming you meant by "operation" the "&&" and "||" operators, the C
answer is the "&&" operator gets evaluated first.

But that's not the right answer, because I don't know that you meant
that, and others reading your code might not know that you meant that,
or even know that's that the C answer.

The correct answer, in order to appease us all sitting here at the
round table, is that you must use parenthesis around the appropriate
pair of binary operands. Pick either (A && B) or (B || C). During the
code review we'll tell you if you're right or wrong. And most likely,
even before that, you'll know whether you're right or wrong.

C lets you get away with a lot of stuff. That doesn't mean you should
necessarily take the freedom to get away with said stuff.

Some organizations, such as MISRA (which deals in part with
safety-critical software), take such "stuff" very seriously, and
impose rules about what you can and cannot do in C. Many of the rules
are, IMHO, seriously worth considering in any type of software.
 
C

Chris Dollin

ivan said:
sorry but i do not have a C book at hand.

what I am saing is:

A && B || C

is the same as:

(A&&B)||C

or the same as:

A&&(B||C)

You're confusing order of evaluation with operand
grouping.

In both `(A && B) || C` and `A && (B || C)` the first
of the two operators to be evaluated [1] is the `&&` and the
first operand to be evaluated is `A`.

This is because && and || are Special and have defined
evaluation ordering. Most [2] of the other C operators
don't. What's more, for both && and || the right-hand
operand is evaluated only if the left-hand operand hasn't
already determined the value of the expression.

[1] Well, if by "operators" we mean "the expressions with
those operators".

[2] The comma /operator/ [3] and the ?: conditional operator
being the other two.

[3] Not the comma that separates function argument expressions.
 
C

CBFalconer

ivan said:
.... snip ...

what I am saing is:

A && B || C

is the same as:

(A&&B)||C

or the same as:

A&&(B||C)

Why bother? Simply use the explicit parenthesis.
 
I

ivan

You're confusing order of evaluation with operand
grouping.

In both `(A && B) || C` and `A && (B || C)` the first
of the two operators to be evaluated [1] is the `&&` and the
first operand to be evaluated is `A`.

This is because && and || are Special and have defined
evaluation ordering. Most [2] of the other C operators
don't. What's more, for both && and || the right-hand
operand is evaluated only if the left-hand operand hasn't
already determined the value of the expression.

So if I got it right it should be:

1. in the case of (A && B) || C: if A=0 then the result is C,
2. in the case of A && (B || C): if A=0 then the result is 0.
3. in the case of A && B || C it evaluates from left to right, hence it is
the same as 1.
4. if I have A || B && C it is the same as (A || B) && C

am I correct?

thanks
ivan
 
C

Chris Dollin

ivan said:
You're confusing order of evaluation with operand
grouping.

In both `(A && B) || C` and `A && (B || C)` the first
of the two operators to be evaluated [1] is the `&&` and the
first operand to be evaluated is `A`.

This is because && and || are Special and have defined
evaluation ordering. Most [2] of the other C operators
don't. What's more, for both && and || the right-hand
operand is evaluated only if the left-hand operand hasn't
already determined the value of the expression.

So if I got it right it should be:

1. in the case of (A && B) || C: if A=0 then the result is C,
2. in the case of A && (B || C): if A=0 then the result is 0.

Yes.
3. in the case of A && B || C it evaluates from left to right,

In the case of `A && B || C`, the grammar forces the grouping
`(A && B) || C`. (Note that this is /not/ "evaluates from
left to right"; in `A || B && C` the grouping is `A || (B && C)`.)
hence it is the same as 1.

Not "hence", but yes, the answer is the same as (1).
4. if I have A || B && C it is the same as (A || B) && C

am I correct?

No, as per my comments on (3). && is more binding than ||;
ie, ||-expressions can have &&-expressions as operands,
but not vice-versa unless bracketed.

I'm going to say this again: there are rules for grouping,
and there are rules for evaluation, and /they are not the
same thing/, although the evaluation rules must respect
the grouping.
 
M

mark_bluemel

ivan said:
is old code

That's good. I have an old book here (Kernighan and Ritchie "The C
Programming Language" 1st edition, dated 1978), which tells me that &&
has higher priority than || so that's OK - "A && B || C" is equivalent
to "(A && B) || C". It also tells me that if "(A && B)" is true, then C
will not be evaluated.

Before putting the file back in to your repository, why not add the
parentheses so that the next time you or someone else reads the file,
they can see what that line of code means straight away?
 
I

Ian Malone

Chris said:
ivan said:
You're confusing order of evaluation with operand
grouping.

In both `(A && B) || C` and `A && (B || C)` the first
of the two operators to be evaluated [1] is the `&&` and the
first operand to be evaluated is `A`.

This is because && and || are Special and have defined
evaluation ordering. Most [2] of the other C operators
don't. What's more, for both && and || the right-hand
operand is evaluated only if the left-hand operand hasn't
already determined the value of the expression.
So if I got it right it should be:

1. in the case of (A && B) || C: if A=0 then the result is C,
2. in the case of A && (B || C): if A=0 then the result is 0.

Yes.

Nit-picking, but the result is 0 or 1. In 1. the result
depends on evaluating C, but C=-1 will still result in
the expression evaluating to one.
 
C

Christopher Benson-Manica

(e-mail address removed) wrote:

(WRT "A && B || C"):
Before putting the file back in to your repository, why not add the
parentheses so that the next time you or someone else reads the file,
they can see what that line of code means straight away?

Am I the only poster who abhors explicit parentheses in such simple
cases? If we are to assume that the code maintainer cannot be trusted
to know or figure out the correct order of evaluation, what argues
against such abominations as

int foo = bar + (baz*quux);

? Or, horrors,

void strcpy( char *dst, char *src ) {
while ( *(dst++) = *(src++) );
}

At some point the maintainer has to be expected to have a reasonable
knowledge of operator precedence so such ugliness can be avoided.
 
C

Chris Dollin

Christopher said:
(e-mail address removed) wrote:

(WRT "A && B || C"):


Am I the only poster who abhors explicit parentheses in such simple
cases?

No. (It depends how complex the A/B/C expressions are, though.)
At some point the maintainer has to be expected to have a reasonable
knowledge of operator precedence so such ugliness can be avoided.

Indeed.
 
J

james of tucson

Christopher said:
Am I the only poster who abhors explicit parentheses in such simple
cases?

You may want to choose your fights more wisely. There is nothing wrong
with parens or braces, and there is nothing wrong with reliance on eval
rules. What I'm saying is, YOU are right, and whoever you are arguing
with is ALSO right. What that means is you can't win, unless you are
literally the policy maker. If it's YOUR project and YOU make the
rules, then by all means, lay down the law.
 
C

Chris Dollin

james said:
You may want to choose your fights more wisely.

He wasn't fighting: he was expressing an opinion.
There is nothing wrong with parens or braces,

In appropriate quantities.

Clutter is clutter. When the helpful-to-the-reader brackets
become troublesome, they are no longer helpful. (Opinions
about how much it takes to be clutter may reasonably vary.)
and there is nothing wrong with reliance on eval rules.

I should jolly well hope not: if one can't rely on the evaluation
rules, one is highly rotated.
What I'm saying is, YOU are right, and whoever you are arguing
with is ALSO right. What that means is you can't win, unless you are
literally the policy maker.

Or if you're not fighting.
 
I

Ian Collins

Chris said:
Christopher Benson-Manica wrote:




No. (It depends how complex the A/B/C expressions are, though.)
Which leads to another guideline; if the expression is complex enough to
require parentheses, it is too complex. Break it down into parts that
don't.
 
B

Bill Pursell

ivan said:
1. in the case of (A && B) || C: if A=0 then the result is C.

Just to make explicit what others have said, in this case, B
is not evaluated. eg:

void
eval(int A)
{
int B, C;
int val;

B = 0;
C = 2;

val = A && (B=1) || C;
printf(" A = %d\n", A);
printf(" A && (B=1) || C evaluates to: %d\n", val);
printf(" B = %d\n", B);
}


When A is non-zero, the expression B=1 is evaluated
and the side effect (assignment to B) takes place.

When A is 0, the overall expression is evaluated
and has the value 1 (not C), but B remains 0.
 
C

Clark S. Cox III

Christopher said:
(e-mail address removed) wrote:

(WRT "A && B || C"):


Am I the only poster who abhors explicit parentheses in such simple
cases?

No, and I'd take it a step further. In most cases, if the expression is
complex enough to require explicit parentheses, then the expression is
too complex and should be broken down into it's constituent parts.

Every time I see parentheses in such a simple expression, my first
thought is: "They must be forcing some non-default grouping", when this
isn't the case then the original programmer just wasted some of my time
and energy.
If we are to assume that the code maintainer cannot be trusted
to know or figure out the correct order of evaluation, what argues
against such abominations as

int foo = bar + (baz*quux);

? Or, horrors,

void strcpy( char *dst, char *src ) {
while ( *(dst++) = *(src++) );
}

At some point the maintainer has to be expected to have a reasonable
knowledge of operator precedence so such ugliness can be avoided.

100% agreed.
 
C

christian.bau

ivan said:
hi all,

if I have:

if(A && B || C)

which operation gets executed first?
If I remeber well should be &&, am I correct?

I have two doubts myself: Why do you post under the russian looking
name "ivan", when it is clear to everybody that you are from india, and
could you please please please tell us why people from India write "I
have a doubt" instead of "I have a question"?
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top