473,406 Members | 2,705 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Logical operator precedence & associativity


/* code start */
int a = 0;
/* expected evaluation and excution order with precedence in mind
/* False(3) , True(1), False(2) */
if ( (a=1) == 0 || 0 != 1 && (a =2) == 1)
putchar('T');
printf("%d", a);
/* code end */

2
"c:\src\test\lcc\test.exe"
Return code 0
Execution time 0.001 seconds
Press any key to continue...

The result shows, code skipped "(a=1) == 0" and expression is false

/* code start */
int a = 0;
/* False(3) , True(1), False(2) */
if ( (a=1) == 0 || 0 != 1 && a == 1)
putchar('T');
printf("%d", a);
/* code end */

T1
"c:\src\test\lcc\test.exe"
Return code 0
Execution time 0.051 seconds
Press any key to continue...

Result shows variable a has been changed as expected though excuted
putchar('T'); statement unexpectedly
logical operator && has higher precedence though both &&, || associates left
to right
so how does evaluation order goes in this code?

feel free to edit comments above in the code to demonstrate execution
order(like number next to True or False)
Nov 11 '06 #1
9 3720
"marko" <ma***@validnow.comwrites:
/* code start */
int a = 0;
/* False(3) , True(1), False(2) */
if ( (a=1) == 0 || 0 != 1 && a == 1)
putchar('T');
printf("%d", a);
/* code end */

T1
(a=1) == 0 is evaluated first. It evaluates to 0, because 1 does
not equal 0. Now "a" has value 1.

Because the left-hand operand of || is 0, now the right-hand
operand must be evaluated. 0 != 1 is true, so the right-hand
operand of && must be evaluated. a == 1 is 1 also, because "a"
was assigned 1, so the result of && is 1. Therefore the result
of || and hence the overall result is 1. Therefore, 'T' is
printed.

--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 11 '06 #2
"Ben Pfaff" <bl*@cs.stanford.eduwrote in message
news:87************@blp.benpfaff.org...
"marko" <ma***@validnow.comwrites:
>/* code start */
int a = 0;
/* False(3) , True(1), False(2) */
if ( (a=1) == 0 || 0 != 1 && a == 1)
putchar('T');
printf("%d", a);
/* code end */

T1

(a=1) == 0 is evaluated first. It evaluates to 0, because 1 does
not equal 0. Now "a" has value 1.

Because the left-hand operand of || is 0, now the right-hand
operand must be evaluated. 0 != 1 is true, so the right-hand
operand of && must be evaluated. a == 1 is 1 also, because "a"
was assigned 1, so the result of && is 1. Therefore the result
of || and hence the overall result is 1. Therefore, 'T' is
printed.

--
int main(void){char
p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int
putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof
p-1;putchar(p[i]\
);}return 0;}
thing still puzzles me is precedence. The test line contains both logical
operator && , || without parenthesis and && has higher precedence yet left
and right operands of || was evaluated first. despite number calculation
case, when * operator and + operator are presented without parenthesis,
left and right side of * operator evaluates first with associativity of left
to right.
something seems conflicting to me
please blow out a fog for me if you have right idea

thank you
Nov 11 '06 #3
marko wrote:
>
if ( (a=1) == 0 || 0 != 1 && a == 1)
thing still puzzles me is precedence.
The test line contains both logical
operator && , || without parenthesis
and && has higher precedence yet left
and right operands of || was evaluated first.
|| has two operands:

(a=1) == 0 is the left operand of ||
0 != 1 && a == 1 is the right operand of ||

The left operand of || was evaluated first.

--
pete
Nov 11 '06 #4
thanks

got it!

"pete" <pf*****@mindspring.comwrote in message
news:45***********@mindspring.com...
marko wrote:
>>
>if ( (a=1) == 0 || 0 != 1 && a == 1)
> thing still puzzles me is precedence.
The test line contains both logical
operator && , || without parenthesis
and && has higher precedence yet left
and right operands of || was evaluated first.

|| has two operands:

(a=1) == 0 is the left operand of ||
0 != 1 && a == 1 is the right operand of ||

The left operand of || was evaluated first.

--
pete

Nov 11 '06 #5
In article <ej**********@aioe.server.aioe.org>
marko <ma***@validnow.comwrote:
thing still puzzles me is precedence. The test line contains both logical
operator && , || without parenthesis and && has higher precedence yet left
and right operands of || was evaluated first.
"Precedence" is not "order of evaluation".

Strictly speaking, ANSI/ISO C does not even have "operator precedence"
(it uses a fully-factored grammar instead). It does have "order
of evaluation", though -- and one grammar may be equivalent to
another, so a precedence-free factored grammar can have the same
set of valid productions as an operator-precedence grammar.

Operator-precedence grammars are easier for people (i.e., "you" :-) )
to deal with, so textbooks on C generally use those.
>... when * operator and + operator are presented without parenthesis,
left and right side of * operator evaluates first with associativity
of left to right.
You must memorize this: "precedence is not order of evaluation".

Precedence (which C formally lacks anyway) simply determines which
operator(s) bind to which arguments, in order to build a parse tree
at compile time.

Order of evaluation happens much later, at run time, and -- in C
at least -- is keyed off of things called "sequence points". A
limited set of C operators provide sequence points, specifically
including the logical operators (&& and ||). They dictate that
*once they are evaluated* (whenever that is), first their left side
is evaluated, then a sequence point occurs, then their right side
is evaluated if and only if the result is not yet known.

So, given:

if (f1() || f2() && f3())

the *operator binding* is:

apply && to result of calling f2() and result of calling f3()

and:

apply || to result of calling f1() and result of <bound group>

which can be drawn as the following tree:

||
/ \
f1() &&
/ \
f2() f3()

The tree that *cannot* be drawn (because C does not allow it, either
through a fully-factored grammar that is painful to write out, or
because of an equivalent grammar in your textbook that uses
"operator precedence") is:

&&
/ \
[WRONG] || f3()
/ \
f1() f2()

The runtime *order of evaluation* is required to be:

- call f1, compare its result to zero
- if this produces TRUE (1), take result, do not do the next few:
- call f2, compare result to zero
- if FALSE (0), take result, do not do:
- call f3, compare result to zero

This would be true even if we used parentheses to force the
compile-time binding to match the second tree, by writing:

if ((f1() || f2()) && f3())

However, in this case, the text version of the runtime sequence
might read (pay attention to indentation):

- call f1, compare result to zero
- if this produces TRUE, take result, do not do:
- call f2, compare result to zero
- if result is FALSE, take result, do not do:
- call f3, compare result to zero

In other words, the conditions upon which f3() are called differ
in the second version, even though both versions call f1() first,
then (if at all) f2(), then (if at all) f3().
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 11 '06 #6
"precedence is not order of evaluation".
bet this pit fall will get many people

so compiler scans code left to right always?
and if compiler sees another portion needs to be evaluated prior to move to
next( f1() = false ), it puts off first portion result and evaluate whole
( f2() && f3()) needed portion which may involve another similar process
(and f2() = true, f3() needs to be evaluated in order to evaluate whole f2
&& f3 portion)
kinda recursive.. it's tree i guess( is it "in order" tree or.. ?)

make it terse, compiler evaluates in sequence which depends on that parse
tree?

appreciate for your presentations

"Chris Torek" <no****@torek.netwrote in message
news:ej*********@news1.newsguy.com...
In article <ej**********@aioe.server.aioe.org>
marko <ma***@validnow.comwrote:
>thing still puzzles me is precedence. The test line contains both
logical
operator && , || without parenthesis and && has higher precedence yet
left
and right operands of || was evaluated first.

"Precedence" is not "order of evaluation".

Strictly speaking, ANSI/ISO C does not even have "operator precedence"
(it uses a fully-factored grammar instead). It does have "order
of evaluation", though -- and one grammar may be equivalent to
another, so a precedence-free factored grammar can have the same
set of valid productions as an operator-precedence grammar.

Operator-precedence grammars are easier for people (i.e., "you" :-) )
to deal with, so textbooks on C generally use those.
>>... when * operator and + operator are presented without parenthesis,
left and right side of * operator evaluates first with associativity
of left to right.

You must memorize this: "precedence is not order of evaluation".

Precedence (which C formally lacks anyway) simply determines which
operator(s) bind to which arguments, in order to build a parse tree
at compile time.

Order of evaluation happens much later, at run time, and -- in C
at least -- is keyed off of things called "sequence points". A
limited set of C operators provide sequence points, specifically
including the logical operators (&& and ||). They dictate that
*once they are evaluated* (whenever that is), first their left side
is evaluated, then a sequence point occurs, then their right side
is evaluated if and only if the result is not yet known.

So, given:

if (f1() || f2() && f3())

the *operator binding* is:

apply && to result of calling f2() and result of calling f3()

and:

apply || to result of calling f1() and result of <bound group>

which can be drawn as the following tree:

||
/ \
f1() &&
/ \
f2() f3()

The tree that *cannot* be drawn (because C does not allow it, either
through a fully-factored grammar that is painful to write out, or
because of an equivalent grammar in your textbook that uses
"operator precedence") is:

&&
/ \
[WRONG] || f3()
/ \
f1() f2()

The runtime *order of evaluation* is required to be:

- call f1, compare its result to zero
- if this produces TRUE (1), take result, do not do the next few:
- call f2, compare result to zero
- if FALSE (0), take result, do not do:
- call f3, compare result to zero

This would be true even if we used parentheses to force the
compile-time binding to match the second tree, by writing:

if ((f1() || f2()) && f3())

However, in this case, the text version of the runtime sequence
might read (pay attention to indentation):

- call f1, compare result to zero
- if this produces TRUE, take result, do not do:
- call f2, compare result to zero
- if result is FALSE, take result, do not do:
- call f3, compare result to zero

In other words, the conditions upon which f3() are called differ
in the second version, even though both versions call f1() first,
then (if at all) f2(), then (if at all) f3().
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to
spammers.

Nov 11 '06 #7
In article <ej**********@aioe.server.aioe.org>,
marko <ma***@validnow.comwrote:
>"precedence is not order of evaluation".
bet this pit fall will get many people

so compiler scans code left to right always?
and if compiler sees another portion needs to be evaluated prior to move to
next( f1() = false ), it puts off first portion result and evaluate whole
( f2() && f3()) needed portion which may involve another similar process
(and f2() = true, f3() needs to be evaluated in order to evaluate whole f2
&& f3 portion)
kinda recursive.. it's tree i guess( is it "in order" tree or.. ?)

make it terse, compiler evaluates in sequence which depends on that parse
tree?
The point to keep in mind is that the compiler doesn't evaluate
expressions - that happens at runtime.

The other point is that the compiler is free to generate code that will
evaluate the subexpressions in "any" order (obvious caveats apply; IOW,
FSVO "any"), as long as it produces the results that the standard requires.

Nov 12 '06 #8

"Kenny McCormack" <ga*****@xmission.xmission.comwrote in message
news:ej**********@news.xmission.com...
In article <ej**********@aioe.server.aioe.org>,
marko <ma***@validnow.comwrote:
>>"precedence is not order of evaluation".
bet this pit fall will get many people

so compiler scans code left to right always?
and if compiler sees another portion needs to be evaluated prior to move
to
next( f1() = false ), it puts off first portion result and evaluate whole
( f2() && f3()) needed portion which may involve another similar process
(and f2() = true, f3() needs to be evaluated in order to evaluate whole f2
&& f3 portion)
kinda recursive.. it's tree i guess( is it "in order" tree or.. ?)

make it terse, compiler evaluates in sequence which depends on that parse
tree?

The point to keep in mind is that the compiler doesn't evaluate
expressions - that happens at runtime.
This is still what i need to know, predicting correct order of evaluation in
a expression. precedence helps to find out the order, but it's not order of
evaluation - thank all for let me know
>
The other point is that the compiler is free to generate code that will
evaluate the subexpressions in "any" order (obvious caveats apply; IOW,
FSVO "any"), as long as it produces the results that the standard
requires.
is subexpressions mean like...

a = b + c * d

since c * d needs to be performed before addition to b, is c * d a
subexpression? or is it something else?
and compiler can perform finding what c is or what d is in any order.
right?

Is there more that I need to aware like this one? Things that common and
gets people. If it's not too long ( maybe just one or two very well known
pit falls ) I need to know and I'd appreciate for posting.
Nov 12 '06 #9
marko wrote:
"Kenny McCormack" <ga*****@xmission.xmission.comwrote in message
news:ej**********@news.xmission.com...
>In article <ej**********@aioe.server.aioe.org>,
marko <ma***@validnow.comwrote:
>>"precedence is not order of evaluation".
bet this pit fall will get many people

so compiler scans code left to right always?
and if compiler sees another portion needs to be evaluated prior to move
to
next( f1() = false ), it puts off first portion result and evaluate whole
( f2() && f3()) needed portion which may involve another similar process
(and f2() = true, f3() needs to be evaluated in order to evaluate whole f2
&& f3 portion)
kinda recursive.. it's tree i guess( is it "in order" tree or.. ?)

make it terse, compiler evaluates in sequence which depends on that parse
tree?
The point to keep in mind is that the compiler doesn't evaluate
expressions - that happens at runtime.

This is still what i need to know, predicting correct order of evaluation in
a expression. precedence helps to find out the order, but it's not order of
evaluation - thank all for let me know
You might think you do but you almost certainly do *not* need to know
the order of evaluation in most situations. What you need to know is
which sub-expressions will be operands of which operators.

The only things in expressions that force a given order of evaluation are:
logical operators && and ||
the left operand is evaluated first and the right *only* if needed

The , operator which is *not* the same as a , in a parameter list

?: where obviously the left operand has to be evaluated first to
determine whether to evaluate the middle or the last operand

function call, where all parameters to a function are evaluated
before the function is called, but they could be evaluated in *any*
order and the order could even change during a run of the program

Of those the only one where I regularly rely on the order of evaluation
is the logical operators, and that is generally for things like
if (ptr != NULL && *ptr==something)
or similar stuff.
>The other point is that the compiler is free to generate code that will
evaluate the subexpressions in "any" order (obvious caveats apply; IOW,
FSVO "any"), as long as it produces the results that the standard
requires.

is subexpressions mean like...

a = b + c * d

since c * d needs to be performed before addition to b, is c * d a
subexpression? or is it something else?
and compiler can perform finding what c is or what d is in any order.
right?
It could first evaluate b, then d, then c, then do the multiplication
then the addition. Thus even though it has to do the multiplication
before the addition it could still evaluate b first.
Is there more that I need to aware like this one? Things that common and
gets people. If it's not too long ( maybe just one or two very well known
pit falls ) I need to know and I'd appreciate for posting.
Look through the comp.lang.c FAQ at http://c-faq.com/ and you will find
lots of things that people get wrong and probably a lot of things you
believe that are wrong.

Except in specific circumstances the order of evaluation is unspecified
and it could be different each time a piece of code is executed.

Array name are *not* constant pointers
An "array" parameters to a function is actually just a pointer parameter

Never use gets

The list of things people get wrong goes on and on, people without
knowledge are endlessly inventive at finding ways to do things wrong.
--
Flash Gordon
Nov 13 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Nameless21 | last post by:
I need to write overloaded operators in C++ by reading their definitions from the input file.how can i write this code. any idea? The problem definition is this: A definition starts with “>...
13
by: Ravi Uday | last post by:
Hi, -I have some confusion on the order in which the operators are evaluated. A statement such as 7/9*9+6-4 is evaluated in which order ? -Which of the following is evaluated first: a) && b)...
20
by: Vivek N | last post by:
Hi Folks, This question may well have been asked and answered before. But, sorry that I couldn't find one from the archives. I typed up this program and compiled it with gcc 3.3.2 main() { int...
80
by: Christopher Benson-Manica | last post by:
Of course one can get the effect with appropriate use of existing operators, but a ^^ operator would make for nice symmetry (as well as useful to me in something I'm working on). Am I the only one...
17
by: Anoob | last post by:
Can we consider () unary operator when calling a function, in exps eq. f(), ( 1 + 2). But when we call function f( 10 ) it is a binary operator. Even if we pass f( 10, 20) as we are using ,...
21
by: siliconwafer | last post by:
Hi, In case of following expression: c = a && --b; if a is 0,b is not evaluated and c directly becomes 0. Does this mean that && operator is given a higher precedence over '--'operator? as...
13
by: Chris | last post by:
I am trying to overload the __invert__ operator (~) such that it can take a second argument, other than self, so that I can express: x ~ y by using: def __invert__(self, other): <do...
32
by: silpau | last post by:
hi, i am a bit confused on expression evaluation order in expressions involving unary increment.decrement operators along with binary operators. For example in the following expression x...
31
by: Jim Langston | last post by:
In Python 2.5 on intel, the statement 2**2**2**2**2 evaluates to 20035299304068464649790723515602557504478254755697514192650169737108940595563114...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.