Why Precedence is not followed?

R

Rupesh

Hello all,
See the code ....


int i=-3,j=2,k=0,m;
m=++i;&&++j||++k;
printf ("%d %d %d %d",i,j,k,m);

I executed this code on gcc. the o/p i had got is:-
-2 3 0 1

Now my question is why k is not getting incremented? As per precedence
of C, first of all, All the unirary increments should take effect. but
in above, first logical operator is evaluated and as left hand side of
logical OR is 1, k do not increment? Then is C's precedence is not
followed here? Plz help????????
 
J

Johan Borkhuis

Rupesh said:
Hello all,
See the code ....


int i=-3,j=2,k=0,m;
m=++i;&&++j||++k; ^??
printf ("%d %d %d %d",i,j,k,m);

I executed this code on gcc. the o/p i had got is:-
-2 3 0 1

Now my question is why k is not getting incremented? As per precedence
of C, first of all, All the unirary increments should take effect. but
in above, first logical operator is evaluated and as left hand side of
logical OR is 1, k do not increment? Then is C's precedence is not
followed here? Plz help????????

See: http://www.eskimo.com/~scs/C-faq/q3.5.html

Also (from K&R, A7.14/A7.15):
For &&: the first operand is evaluated, including all side effects; if
it is equal to 0, the value of the expression is 0. Otherwise, the right
operand is evaluated, and if it is equal to 0, the expression's value is
0, otherwise 1.
For ||: the first operand is evaluated, including all side effects; if
it is unequal to 0, the value of the expression is 1. Otherwise, the
right operand is evaluated, and if it is unequal to 0, the expression's
value is 1, otherwise 0.

So the behaviour is completely correct, the expression k++ is not evaluated.

Kind regards,
Johan

--
o o o o o o o . . . _____J_o_h_a_n___B_o_r_k_h_u_i_s___
o _____ || http://www.borkhuis.com |
.][__n_n_|DD[ ====_____ | (e-mail address removed) |
>(________|__|_[_________]_|________________________________|
_/oo OOOOO oo` ooo ooo 'o!o!o o!o!o`
== VxWorks FAQ: http://www.xs4all.nl/~borkhuis/vxworks/vxworks.html ==
 
K

Keith Thompson

Rupesh said:
Hello all,
See the code ....


int i=-3,j=2,k=0,m;
m=++i;&&++j||++k;
printf ("%d %d %d %d",i,j,k,m);

I executed this code on gcc. the o/p i had got is:-
-2 3 0 1

Now my question is why k is not getting incremented? As per precedence
of C, first of all, All the unirary increments should take effect. but
in above, first logical operator is evaluated and as left hand side of
logical OR is 1, k do not increment? Then is C's precedence is not
followed here? Plz help????????

The code you posted contained a syntax error, which makes the think
it's not the actual code you compiled.

Please post the *exact* code you compiled. Don't re-type it;
cut-and-paste it. And post a complete (short) program, not a code
fragment.

There's no point in asking us to guess which errors are in your actual
code and which you introduced when you re-typed it.
 
J

junky_fellow

Rupesh said:
Hello all,
See the code ....


int i=-3,j=2,k=0,m;
m=++i;&&++j||++k;
printf ("%d %d %d %d",i,j,k,m);

I executed this code on gcc. the o/p i had got is:-
-2 3 0 1

Now my question is why k is not getting incremented? As per precedence
of C, first of all, All the unirary increments should take effect. but
in above, first logical operator is evaluated and as left hand side of
logical OR is 1, k do not increment? Then is C's precedence is not
followed here? Plz help????????

Read about the "Logical OR" and "Logical AND" operators from some
good book of C.
The statement,
m=++i;&&++j||++k;
doesn't even compile. Perhaps you meant
m=++i&&++j||++k;

Reason why k in not incremented, is that
If the first operand of the Logical OR operator compares unequal to 0,
the second operand is not evaluated.

If the first operand of Logical AND operator compares equal to 0,
second operand is not evaluated.
 
L

Lawrence Kirby

Hello all,
See the code ....


int i=-3,j=2,k=0,m;
m=++i;&&++j||++k;

I assume you mean

m=++i&&++j||++k;

but a few spaces make this a lot clearer:

m = ++i && ++j || ++k;
printf ("%d %d %d %d",i,j,k,m);

I executed this code on gcc. the o/p i had got is:-
-2 3 0 1

Now my question is why k is not getting incremented?

Because || is a short-circuit operator - when its left hand operand is
unequal to zero its right operand is not evaluated.
As per precedence
of C, first of all, All the unirary increments should take effect.

No, you are confusing precedence with (order of) evaluation, they are not
the same thing. Precedence tells you how an expression is grouped i.e.
what operands go with what operators. For example given

(++i&&++j) (spaces removed to avoid indicating a grouping)

the fact that ++ has higher precedence than && tells is that this is
grouped as

(++i) && (++j)

and not

++(i && ++j)

i here could be bound to an operator on its left or on its right. It is
bound to the operator with higher precedence. Notice that j only has an
operator on its left in this example i.e. there is no ambiguity for
precedence to resolve. In the full example

m = ++i && ++j || ++k;

j has an operator on its right as well and like i it is bound to the
operator with higher precedence i.e. ++. k is now an operand with nothing
on its right so it is simply bound to the operator on its left. At this
point we have the partial grouping:

m = (++i) && (++j) || (++k);

The expressions (++i) (++j) and (++k) and not forgetting m are themselves
operands. && has higher precedence than both = and || so (++i) and (++j)
are bound to it:

m = ((++i) && (++j)) || (++k);

The operand ((++i) && (++j)) has operators on its left and right and is
bound to the one with higher precedence i.e. || giving

m = (((++i) && (++j)) || (++k));

The final 2 operands m and (((++i) && (++j)) || (++k)) are bound to the
only remaining operator =. Now we have a parse of the expression the next
step is to evaluate it. Evaluation has nothing to do with precedence,
we're finished with that. Consider evaluation top down. The top level
operator is = which evaluates its left and right operands (the left must
be an lvalue). The right operand of = is the result of the || operator.
The || operator evaluates its left operand, tests it, and evaluates its
right operand if it is zero. The left operand of || is the result of the
&& operator. && evaluates its left operand and if non-zero evaluates its
right operand. (++i) is -2 so the right operand of && i.e. (++j) is
evaluated. This evaluates to 3 which is also non-zero so the result of &&
is 1. Since this left operand of || is non-zero || doesn't evaluate its
right operand i.e. (++k) isn't evaluated at all.

This sounds more complex than it really is. Just remember that when an
operator like && or || doesn't evaluate its right operand that refers to
the whole expression that makes up the right operand, in this case ++k for ||.

Lawrence
 
K

Kenneth Brody

Netocrat said:
int i=-3,j=2,k=0,m;
m=++i;&&++j||++k;
printf ("%d %d %d %d",i,j,k,m);
[...]
The program below should explain things for you. Kindly copy and paste it
into a separate file and present it to your standards-compliant compiler.
Run the program and carefully note the output. Best Regards.

P.S. Perhaps you could enlighten me as to whether applying the ! operator
to the return of function they is a portable thing to do.

#include <stdio.h>

#define /*Your question*/ about "the || operator is not "
#define often "evaluated " /* in this newsgroup, */
#define so "when " /* I saw it I realised that */ [...snip...]
for (what; reason;s) do {you; fwrite(such code, as, you, did)?
my_guess: trolling || new && naive;}
while (many(learn, by, fread(newsgroups,
like, c.l.c && asking, questions)));
if (they((post*) code) == your code)
for (better; they(learn); more) from else where;
then; return when(!they(ignorant),
of_more_appropriate_sources
(F.A.Q || textbook || website));}

Some people have *way* too much time on their hands. :)

(I, of course, having just a tiny bit too much time on my hands, compiled
and ran it.)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
N

Netocrat

Hello all,
See the code ....


int i=-3,j=2,k=0,m;
m=++i;&&++j||++k;
printf ("%d %d %d %d",i,j,k,m);

I executed this code on gcc. the o/p i had got is:-
-2 3 0 1

Now my question is why k is not getting incremented? As per precedence
of C, first of all, All the unirary increments should take effect. but
in above, first logical operator is evaluated and as left hand side of
logical OR is 1, k do not increment? Then is C's precedence is not
followed here? Plz help????????

The program below should explain things for you. Kindly copy and paste it
into a separate file and present it to your standards-compliant compiler.
Run the program and carefully note the output. Best Regards.

P.S. Perhaps you could enlighten me as to whether applying the ! operator
to the return of function they is a portable thing to do.


#include <stdio.h>

#define /*Your question*/ about "the || operator is not "
#define often "evaluated " /* in this newsgroup, */
#define so "when " /* I saw it I realised that */
#define it " is true"
#define that "the left"/*ist commies in c.l.c suppress */ it "\n"
#define The "right of " /*discussion*/ about /* the || operator is */\
often /* repressed */ so that
#define w "he "/*n it arises few of us understand it.*/ The
long /*list of the*/ many (char/*acters*/ *who, float/*ed*/
by, size_t /*up the*/situation){/*and*/ return/*ed home
with */ 0 /* knowledge*/;}/*is*/ int/*eterpreted*/ by,
/*the*/ naive, /*as due to*/ new, trolling;
typedef /*Actually, the*/ char/*isma of those*/ post/*ers*/;
#define did /*the opposite. It is a */ stderr /*that for*/
#define s/*ome*/ reason++ /* incoherence */
#define plus /* smileys like these: "^x^"*/" ^"/*<_> /\ <_>*/
/*are*/ int/*erpreted*/ when(int/*ense and*/ profuse,
/* as un*/int/*elligent*/ rantings) {/*of*/
return/*ing*/ 0/*s.*/;}
/*Those "rantings", like the white*/ char/*coal*/ *they(
char/*acterise, are*/ *real/*ly the*/){/*insights of
coders*/ return/*ed*/ /*from a higher*/ real/*ity*/;}
/*They seek to*/ int/*erpret and inform us*/
of_more_appropriate_sources(/* of C knowledge that*/
short/*ly they will make*/ available){/*to those who*/
return /*their copy of the standard. A $*/30;} /*refund
will be*/ post/*ed to those who*/ *learn, /* that to be */
*ignorant="of the standard"; /* is not the */
#define end "\nT"/*o*/ w/*homever insults their*/
int/*elligence and */ reason/* they may retort
that -1*/=-1;
/* Such profundity will remain */ long /*after*/
what/*ever benefit your safety initialisor i*/=0;
char/*ried to the*/ newsgroups[1]; /* Maintain */int/*erest
in their wisdom - */ my_guess, /* is */ more; /* posts of
larger*/ size_t/*o spread the message of the new breed*/
like /* it deserves to be - */ = /* to the*/ sizeof( /* the
heart of the most intrepid of lurkers in the */
newsgroups);
#define /* a heart that*/ questions stdin/*terpretations of */
float/*ing point comparisons, seeks the */ website/*s*/,
where, better /*than*/, textbook, /*knowledge accretes*/
then, asking /*only if the*/ =9; /*lives of a cat are
enough to in*/struct {/*the unin*/struct/*able*/ {
char/*ts the */ c;} l/*anguage to*/;} c/*limactic
heights*/={{'1'}}; /*The*/ struct/*ures unleashed by the
new breed will be of*/ {/*indes*/struct/*able*/
{/*ma*/int/*enance-free*/ Q/*uality*/;} A/*ssured not
to*/;} F/*ail. Free*/;
#define from /*all*/ break/*ages*/;

/*The*/ post/*ed*/ code[] /*as a string is*/ =
"int i=-3,j=2,k=0,m;\n" \
"m=++i;&&++j||++k;\n" \
plus \
"\nprintf (\"%d %d %d %d\",i,j,k,m);\n" \
end;
size_t as=sizeof(code);

/* Reading the code below should explain the problem.
*/

#define your (char*)/*acter*/ /* differently */
#define such (char/*acter*/*)/* as capable of independently */
/*learning the*/ int/*egral and*/ main(/*concepts of C programming,
A*/void){ int/*eracting before*/ you=1/*st observe the forum.*/;

for (what; reason;s) do {you; fwrite(such code, as, you, did)?
my_guess: trolling || new && naive;}
while (many(learn, by, fread(newsgroups,
like, c.l.c && asking, questions)));
if (they((post*) code) == your code)
for (better; they(learn); more) from else where;
then; return when(!they(ignorant),
of_more_appropriate_sources
(F.A.Q || textbook || website));}
 
O

Old Wolf

Netocrat said:
P.S. Perhaps you could enlighten me as to whether applying the ! operator
to the return of function they is a portable thing to do.

If you're asking about the behaviour of:

char *they(char *);

while (!they("of the standard")) { /*....*/ }

then the answer is yes, it is the same as comparing the result to 0,
ie. evaluates to 0 if the returned pointer is null, otherwise
evaluates to 1.
 
N

Netocrat

If you're asking about the behaviour of:

char *they(char *);

while (!they("of the standard")) { /*....*/ }

then the answer is yes, it is the same as comparing the result to 0,
ie. evaluates to 0 if the returned pointer is null, otherwise
evaluates to 1.

Tsk, tsk, that was supposed to be a research assignment for the OP.

But your post supports the moral that a house not built of bricks will be
blown down by the wolf. Whatever material this one was, it wasn't bricks.
 
K

Krishanu Debnath

Netocrat wrote:

for (better; they(learn); more) from else where;
then; return when(!they(ignorant),
of_more_appropriate_sources
(F.A.Q || textbook || website));}

Did you compile your code with 'warning flags' on? :)

Krishanu
 
R

Rupesh

Hello All,
Sorry for posting syntaxically wrong code. But all of u had got the
mistake as u had guessed.
OK
thanks Lawrence Kirby for ur detailed answer it cleared my concept
regarding precedence in C.
Thanks all,
For ur contributions,
Rupesh..
 
N

Netocrat

Netocrat wrote:



Did you compile your code with 'warning flags' on? :)

I'd like to plead ignorance, but I can't. You weren't supposed to
notice...

My code rejects gcc's suggestion that it cuddle the operands to && in
parentheses, but it accepts that the unused variable and no-effect
statement warnings are an unsightly blight. OK, so you found a weak link,
however my code commends your polite restraint in not mentioning its
excessive use of #defines and comments and the lack of obscurity of its
output string after pre-processing...

In its defence the code was composed fairly quickly in a single session.

Oh, by the way, I forgot to mention the licence. It's GNL (General
Netocrat Licence aka General Newsgroup Licence): anyone who comments on
the code is required to improve it (or substitute it with new code of
their own creation). ;-)

Under the GNL no personal modifications are permitted: all modifications
must be posted publicly. An improvement in one area must not be at the
expense of another area. Standards-compliant code is, of course,
mandatory.
 

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
474,169
Messages
2,570,915
Members
47,456
Latest member
JavierWalp

Latest Threads

Top