By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,238 Members | 1,804 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,238 IT Pros & Developers. It's quick & easy.

Logical And

P: n/a
sam
Please look at the code below
#include <stdio.h>

int expr(char str[], int i){
printf("%s \n",str);
return i;
}

int main()
{
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
return 0;
}

output
-------
1st

As && has an higher precedence over ||
then it should call expr("2nd",0) or expr("3rd",0)
first then why it calls (expr("1st",1) first

Regards
Shiju
Nov 14 '05 #1
Share this Question
Share on Google+
34 Replies


P: n/a
sh**********@hotmail.com (sam) wrote in
news:25**************************@posting.google.c om:
Please look at the code below
#include <stdio.h>

int expr(char str[], int i){
printf("%s \n",str);
return i;
}

int main()
{
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
return 0;
}

output
-------
1st

As && has an higher precedence over ||
then it should call expr("2nd",0) or expr("3rd",0)
first then why it calls (expr("1st",1) first


It's called a short-circuit. If expr("1st",1) is true, then there is no
need to bother evaluting expr("3rd",0) and then expr("2nd",0), so it does
not. What you have seen is correct.

--
- Mark ->
--
Nov 14 '05 #2

P: n/a
sam <sh**********@hotmail.com> spoke thus:
int main()
{
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
return 0;
} As && has an higher precedence over ||
then it should call expr("2nd",0) or expr("3rd",0)
first then why it calls (expr("1st",1) first


Does this make sense?

* > +
A + B * C equals A + (B * C)

&& > ||
A || B && C equals A || (B && C)

As Mark stated, the last expression is subject to short-circuit
evaluation, and thus there is no need to evaluate B && C (since A is
true in this case). Notice that

B && C || A

in this case calls #2 and #1, but not #3, again because of
short-circuit evaluation.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #3

P: n/a
sam wrote:

Please look at the code below

#include <stdio.h>

int expr(char str[], int i){
printf("%s \n",str);
return i;
}

int main()
{
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
return 0;
}

output
-------
1st

As && has an higher precedence over ||
then it should call expr("2nd",0) or expr("3rd",0)
first then why it calls (expr("1st",1) first


"Operator precedence" and "order of evaluation" are
two different things. Precedence dictates that the
expression means

expr("1st",1) || ( expr("2nd",0) && expr("3rd",0) )

rather than

( expr("1st",1) || expr("2nd",0) ) && expr("3rd",0)

.... but precedence alone doesn't determine the order in
which the three expr() calls are made.

The evaluation order is determined not by the precedence,
but by the definitions of the || and && operators. In this
case, the rule for || says that if expr("1st",1) produces a
non-zero value, the second sub-expression is not evaluated
at all. If the expr("1st",1) yields zero, the second sub-
expression *is* evaluated -- and in that evaluation, there
is a similar rule for && that governs the order in which
expr("2nd",0) and expr("3rd",0) are evaluated.

Summary: Operator precedence governs the meaning of an
expression with multiple operators, but does not control
the order in which the operands are evaluated.

--
Er*********@sun.com
Nov 14 '05 #4

P: n/a
Mark A. Odell writes:

Please look at the code below
#include <stdio.h>

int expr(char str[], int i){
printf("%s \n",str);
return i;
}

int main()
{
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
return 0;
}

output
-------
1st

As && has an higher precedence over ||
then it should call expr("2nd",0) or expr("3rd",0)
first then why it calls (expr("1st",1) first


It's called a short-circuit. If expr("1st",1) is true, then there is no
need to bother evaluting expr("3rd",0) and then expr("2nd",0), so it does
not. What you have seen is correct.


This is nasty stuff! Once prompted, I remember the short circuit rule and
how I once wanted such a rule in Pascal. But digging this rule out of the
BNF for C seems like a real challenge. However I would expect it to be
noticeable in syntax charts. Does any one know of a site containing syntax
charts for C? I looked and failed to find one. I know there is a book, I
saw one several years ago, but I didn't like it.

Nov 14 '05 #5

P: n/a
"osmium" <r1********@comcast.net> wrote in
news:bu************@ID-179017.news.uni-berlin.de:
> int main()
> {
> if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
> return 0;
> }
>
> output
> -------
> 1st
>
> As && has an higher precedence over ||
> then it should call expr("2nd",0) or expr("3rd",0)
> first then why it calls (expr("1st",1) first


It's called a short-circuit. If expr("1st",1) is true, then there is no
need to bother evaluting expr("3rd",0) and then expr("2nd",0), so it
does not. What you have seen is correct.


This is nasty stuff!


Nasty nothing. It's dog simple.

if (a || b)

Why on earth would you ever evaluate b if a is true? Very simple. I
believe we need to think about sequence points here.

--
- Mark ->
--
Nov 14 '05 #6

P: n/a
osmium wrote:

Mark A. Odell writes:

It's called a short-circuit. If expr("1st",1) is true, then there is no
need to bother evaluting expr("3rd",0) and then expr("2nd",0), so it does
not. What you have seen is correct.
This is nasty stuff! Once prompted, I remember the short circuit rule and
how I once wanted such a rule in Pascal. But digging this rule out of the
BNF for C seems like a real challenge.


A challenge, indeed, because the short-circuit rule is
not present in the BNF in the first place.
However I would expect it to be
noticeable in syntax charts.


Why? The syntax will tell you what arrangements of
symbols are valid C utterances, but will say nothing about
what those utterances mean (if, indeed, they mean anything
at all).

--
Er*********@sun.com
Nov 14 '05 #7

P: n/a
Mark A. Odell wrote:
"osmium" <r1********@comcast.net> wrote in
[...snip...]
Nasty nothing. It's dog simple.

if (a || b)

Why on earth would you ever evaluate b if a is true?


If this wasn't a rhetorical question, I /could/ think of an answer. For
example: short-circuit evaluation may, under some circumstances,
negatively impact the size and/or speed of generated assembly code
(e.g., by introducing pipeline stalls).

Best regards, Sidney

Nov 14 '05 #8

P: n/a
Eric Sosman wrote:

(snip)
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));

(snip)
... but precedence alone doesn't determine the order in
which the three expr() calls are made. The evaluation order is determined not by the precedence,
but by the definitions of the || and && operators. In this
case, the rule for || says that if expr("1st",1) produces a
non-zero value, the second sub-expression is not evaluated
at all. If the expr("1st",1) yields zero, the second sub-
expression *is* evaluated -- and in that evaluation, there
is a similar rule for && that governs the order in which
expr("2nd",0) and expr("3rd",0) are evaluated.

Summary: Operator precedence governs the meaning of an
expression with multiple operators, but does not control
the order in which the operands are evaluated.


Funny. There is a very similar discussion in comp.lang.fortran,
except that Fortran does not guarantee short circuit evaluation.

The discussion of precedence and evaluation order is there, though.

-- glen

Nov 14 '05 #9

P: n/a
Sidney Cadot wrote:

Mark A. Odell wrote:
"osmium" <r1********@comcast.net> wrote in

[...snip...]
Nasty nothing. It's dog simple.

if (a || b)

Why on earth would you ever evaluate b if a is true?


If this wasn't a rhetorical question, I /could/ think of an answer. For
example: short-circuit evaluation may, under some circumstances,
negatively impact the size and/or speed of generated assembly code
(e.g., by introducing pipeline stalls).


You're missing the point, I think. Short-circuit
evaluation isn't about efficiency, but about correctness.
The || and && operators are *defined* to work this way;
an implementation that evaluated `b' when `a' was true
would not be an implementation of C.

--
Er*********@sun.com
Nov 14 '05 #10

P: n/a
"Mark A. Odell" <no****@embeddedfw.com> writes:
[...]
Nasty nothing. It's dog simple.

if (a || b)

Why on earth would you ever evaluate b if a is true? Very simple. I
believe we need to think about sequence points here.


The && and || operators short-circuit because the standard says so.
It's not at all obvious that they need to. There are at least four
possible ways this could have been defined, and I think there are
languages that implement each of them:

1. The logical "and" and "or" operators (however they're spelled)
always short-circuit (C, C++, Perl, etc.).

2. The "and" and "or" operators never short-circuit (Pascal, I think).

3. It's unspecified or implementation-defined whether they
short-circuit; code that assumes either that they do or that they
don't is potentially non-portable (I don't know of an example of
this).

4. The language provides variant forms, letting the programmer decide
whether short-circuiting is desired (Ada has "and" and "or", which
don't short-circuit, and "and then" and "or else", which do).

On modern CPUs, a non-short-circuiting form can actually improve
performance in some cases by avoiding pipeline stalls. The fact that
C doesn't provide an easy way to do this is partly a result of the
fact that the language was defined before pipeline stalls were much of
an issue.

I would geuss that some optimizing C compilers can transform "&&" and
"||" to non-short-circuiting forms if they can prove the RHS has no
side effects and doesn't depend on the LHS.

Of course short-circuiting is extremely useful for things like:

if (ptr != NULL && *ptr != 0) { ... }

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #11

P: n/a
Eric Sosman wrote:
Sidney Cadot wrote:
Mark A. Odell wrote:

"osmium" <r1********@comcast.net> wrote in

Why on earth would you ever evaluate b if a is true?
If this wasn't a rhetorical question, I /could/ think of an answer. For
example: short-circuit evaluation may, under some circumstances,
negatively impact the size and/or speed of generated assembly code
(e.g., by introducing pipeline stalls).

You're missing the point, I think.


Umm no, I don't think so. I was merely following my instincts, which
invariably make me answer seemingly rhetorical questions.
Short-circuit evaluation isn't about efficiency, but about correctness.
The || and && operators are *defined* to work this way;
an implementation that evaluated `b' when `a' was true
would not be an implementation of C.


According to the "as if" principle, a compiler is perfectly free to do
this given the right circumstances. And, in fact, it may just be the
clever thing to do. Consider:

int proof_of_concept(void)
{
int a,b,c,d;

a = function_returning_int()!=0;
b = function_returning_int()!=0;
c = function_returning_int()!=0;
d = function_returning_int()!=0;

return a||b||c||d;
}

The best (fastest & shortest) translation of the return expression
evaluation for most architectures would be to just use the binary-or
operator on a, b, c, and d.

The alternative would involve a lot of branching, which is really
significantly slower on many architectures.

Whether any compiler is actually smart enough to do this: I doubt it!

Best regards, Sidney

Nov 14 '05 #12

P: n/a
Keith Thompson wrote:
[...]
On modern CPUs, a non-short-circuiting form can actually improve
performance in some cases by avoiding pipeline stalls. The fact that
C doesn't provide an easy way to do this is partly a result of the
fact that the language was defined before pipeline stalls were much of
an issue.


"C doesn't provide?" Perhaps you've forgotten

if (a || b) vs. if (a | b)
if (a && b) vs. if (a & b)

.... except that in some circumstances you might need to
write the last of these as `if (!!a & !!b)'. At any rate,
C does in fact provide non-short-circuited forms if you
want them.

--
Er*********@sun.com
Nov 14 '05 #13

P: n/a
Sidney Cadot wrote:

Eric Sosman wrote:
Sidney Cadot wrote:
Mark A. Odell wrote:
"osmium" <r1********@comcast.net> wrote in

Why on earth would you ever evaluate b if a is true?

If this wasn't a rhetorical question, I /could/ think of an answer. For
example: short-circuit evaluation may, under some circumstances,
negatively impact the size and/or speed of generated assembly code
(e.g., by introducing pipeline stalls).

You're missing the point, I think.


Umm no, I don't think so. I was merely following my instincts, which
invariably make me answer seemingly rhetorical questions.
Short-circuit evaluation isn't about efficiency, but about correctness.
The || and && operators are *defined* to work this way;
an implementation that evaluated `b' when `a' was true
would not be an implementation of C.


According to the "as if" principle, [...]


Ah, well, yes, of course. Perhaps I should have written
"An implementation that permitted the program to observe that
`b' had been evaluated ..." Schrödinger was a compiler writer
(at least, that's what Heisenberg may have said).

--
Er*********@sun.com
Nov 14 '05 #14

P: n/a
Eric Sosman wrote:
Keith Thompson wrote:
[...]
On modern CPUs, a non-short-circuiting form can actually improve
performance in some cases by avoiding pipeline stalls. The fact that
C doesn't provide an easy way to do this is partly a result of the
fact that the language was defined before pipeline stalls were much of
an issue.

"C doesn't provide?" Perhaps you've forgotten

if (a || b) vs. if (a | b)
if (a && b) vs. if (a & b)


....And next time someone has the temerity to suggest that Pascal doesn't
provide short-circuit evaluation, I will be sure to point out the error
of their thinking by showing how it can be simulated in Pascal :-)

Personally, I wouldn't consider using bit-ops an easy way to emulate
non-short-circuit evaluation, given the interpretation of true as
"anything un-equal to zero". As you rightly point out, this can be
overcome by using !!x or (x!=0) for any boolean operand, but it's still
a bit clumsy, and quite error-prone. Proper operators for this would be
nice-to-have.

Best regards,

Sidney

Nov 14 '05 #15

P: n/a
Eric Sosman <Er*********@sun.com> writes:
Keith Thompson wrote:
[...]
On modern CPUs, a non-short-circuiting form can actually improve
performance in some cases by avoiding pipeline stalls. The fact that
C doesn't provide an easy way to do this is partly a result of the
fact that the language was defined before pipeline stalls were much of
an issue.


"C doesn't provide?" Perhaps you've forgotten

if (a || b) vs. if (a | b)
if (a && b) vs. if (a & b)

... except that in some circumstances you might need to
write the last of these as `if (!!a & !!b)'. At any rate,
C does in fact provide non-short-circuited forms if you
want them.


If by "some circumstances" you mean "nearly all circumstances",
perhaps.

If I saw code that used "if (a & b)", my first assumption would be
that it was a typo for "if (a && b)", and my second would be that the
author really intended to test the bitwise "and" of a and b. If there
were a comment explaining that it's really a logical "and", using "&"
rather than "&&" to avoid pipeline stalls, I'd spend a long time
trying to figure out (1) how it's known that the values of a and b
cannot be anything other 0 or 1, and (2) why the author thought this
micro-optimization was worth the time I'm spending thinking about it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #16

P: n/a
On Tue, 13 Jan 2004 17:43:12 -0500, Eric Sosman <Er*********@sun.com>
wrote in comp.lang.c:
Keith Thompson wrote:
[...]
On modern CPUs, a non-short-circuiting form can actually improve
performance in some cases by avoiding pipeline stalls. The fact that
C doesn't provide an easy way to do this is partly a result of the
fact that the language was defined before pipeline stalls were much of
an issue.


"C doesn't provide?" Perhaps you've forgotten

if (a || b) vs. if (a | b)
if (a && b) vs. if (a & b)

... except that in some circumstances you might need to
write the last of these as `if (!!a & !!b)'. At any rate,
C does in fact provide non-short-circuited forms if you
want them.


Yes, "!!" in C is the "Booleanization" operator for scalar types.

In C99:

if (_Bool(a) | _Bool(b))

....of course, bool may be substituted for _Bool if <stdbool.h> is
included.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #17

P: n/a
Jack Klein wrote:
In C99:

if (_Bool(a) | _Bool(b))


ITYM

if ((_Bool)a | (_Bool)b)

(assuming you got mixed up with C++ constructor syntax).

Jeremy.
Nov 14 '05 #18

P: n/a
Eric Sosman wrote:
sam wrote:

Please look at the code below

#include <stdio.h>

int expr(char str[], int i){
printf("%s \n",str);
return i;
}

int main()
{
if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));
return 0;
}

output
-------
1st

As && has an higher precedence over ||
then it should call expr("2nd",0) or expr("3rd",0)
first then why it calls (expr("1st",1) first


"Operator precedence" and "order of evaluation" are
two different things. Precedence dictates that the
expression means

expr("1st",1) || ( expr("2nd",0) && expr("3rd",0) )

rather than

( expr("1st",1) || expr("2nd",0) ) && expr("3rd",0)

... but precedence alone doesn't determine the order in
which the three expr() calls are made.

The evaluation order is determined not by the precedence,
but by the definitions of the || and && operators. In this
case, the rule for || says that if expr("1st",1) produces a
non-zero value, the second sub-expression is not evaluated
at all. If the expr("1st",1) yields zero, the second sub-
expression *is* evaluated -- and in that evaluation, there
is a similar rule for && that governs the order in which
expr("2nd",0) and expr("3rd",0) are evaluated.

Summary: Operator precedence governs the meaning of an
expression with multiple operators, but does not control
the order in which the operands are evaluated.


Finally a sensible answer in this thread. A corollary is: If you
want to use complex logical expressions, parenthise them so there
is NO DOUBT, NO DOUBT WHATSOEVER, what they mean. You will save a
lot of headaches, both your own and others.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #19

P: n/a
On 14 Jan 2004 02:26:03 GMT, Jeremy Yallop
<je****@jdyallop.freeserve.co.uk> wrote in comp.lang.c:
Jack Klein wrote:
In C99:

if (_Bool(a) | _Bool(b))


ITYM

if ((_Bool)a | (_Bool)b)

(assuming you got mixed up with C++ constructor syntax).

Jeremy.


Do you think in the next upgrade to the C++ standard they should add a
<stdbool> header that defines the macro _Bool to bool?

Thanks for correcting brain fart.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #20

P: n/a
In <bu**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
Eric Sosman wrote:
Sidney Cadot wrote:
Mark A. Odell wrote:
"osmium" <r1********@comcast.net> wrote in

Why on earth would you ever evaluate b if a is true?

If this wasn't a rhetorical question, I /could/ think of an answer. For
example: short-circuit evaluation may, under some circumstances,
negatively impact the size and/or speed of generated assembly code
(e.g., by introducing pipeline stalls).

You're missing the point, I think.


Umm no, I don't think so. I was merely following my instincts, which
invariably make me answer seemingly rhetorical questions.
Short-circuit evaluation isn't about efficiency, but about correctness.
The || and && operators are *defined* to work this way;
an implementation that evaluated `b' when `a' was true
would not be an implementation of C.


According to the "as if" principle, a compiler is perfectly free to do
this given the right circumstances. And, in fact, it may just be the
clever thing to do.


But the point is that it can do it *only* when the program can't tell
the difference. Fortran programmers often wish they could do things
like:

if (a == 0 || b / a > 0) /* do something */ ;

The short circuiting feature of || and && is not an optimisation feature,
its purpose is to make the language easier to use. Without it, the
above statement would have to be rewritten as:

if (a == 0) /* do something */ ;
else if (b / a > 0) /* do it again */ ;

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #21

P: n/a
Da*****@cern.ch (Dan Pop) writes:
[...]
The short circuiting feature of || and && is not an optimisation feature,
its purpose is to make the language easier to use.
above statement would have to be rewritten as:


I suspect it would be more accurate to say that it's not *just* an
optimization feature. Efficiency may also have been a concern when
the feature was first designed (probably in one of C's ancestors).

It's a happy coincidence that ease of use and efficiency (on the
hardware of the time) both led to the same design decision.

I haven't looked at the relevant historical documents lately, so I'm
only guessing here.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #22

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
[...]
The short circuiting feature of || and && is not an optimisation feature,
its purpose is to make the language easier to use.
above statement would have to be rewritten as:


I suspect it would be more accurate to say that it's not *just* an
optimization feature. Efficiency may also have been a concern when
the feature was first designed (probably in one of C's ancestors).

It's a happy coincidence that ease of use and efficiency (on the
hardware of the time) both led to the same design decision.

I haven't looked at the relevant historical documents lately, so I'm
only guessing here.


I was using the *present* tense, so whatever was the case when the
feature was introduced is irrelevant to my statement.

As demonstrated in this thread, depending on the context, the feature
may or may not optimise the execution speed. I suspect this has always
been the case (in trivial cases, ORing/ANDing everything together is
faster than checking the value of each operand). In principle, the
compiler should be able to detect the cases when the as-if rule allows
non-short circuiting evaluation and and take advantage of it when it
improves the execution speed, but I doubt that many compilers bother
performing such checking.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23

P: n/a
Keith Thompson wrote:
If I saw code that used "if (a & b)", my first assumption would be
that it was a typo for "if (a && b)", and my second would be that the
author really intended to test the bitwise "and" of a and b.


When writing something like "if (a & b)" it is a good idea to
write "if (a & b) /*bitwise*/" instead.
On the other hand it looks a little bit funny to me, just like
some beginner who writes "int i; /*an integer variable*/" ;-)

So I for myself always use "if (a bitand b)" instead of
"if (a & b)" (after including <iso646.h> of course),
because with this notation it should be obvious to see that I
did *really* mean & and not &&.

-rb
--
Ro*************@rbdev.net
Nov 14 '05 #24

P: n/a
Robert Bachmann <Ro*************@rbdev.net> wrote in
news:40***********************@newsreader02.highwa y.telekom.at:
If I saw code that used "if (a & b)", my first assumption would be
that it was a typo for "if (a && b)", and my second would be that the
author really intended to test the bitwise "and" of a and b.


When writing something like "if (a & b)" it is a good idea to
write "if (a & b) /*bitwise*/" instead.


What's next? When writing this do we need the comment shown?

idx++; /* Increment 'idx' */

just because it might confuse a beginner? You, the developer must write
the code you intend to write. Why should I not believe you meant bit-AND
if you write?

if (reg_a_bits & reg_a_field_mask)

What is so wrong about C that people aren't comfortable with it?

--
- Mark ->
--
Nov 14 '05 #25

P: n/a
"Mark A. Odell" <no****@embeddedfw.com> writes:
Robert Bachmann <Ro*************@rbdev.net> wrote in
news:40***********************@newsreader02.highwa y.telekom.at:
If I saw code that used "if (a & b)", my first assumption would be
that it was a typo for "if (a && b)", and my second would be that the
author really intended to test the bitwise "and" of a and b.
When writing something like "if (a & b)" it is a good idea to
write "if (a & b) /*bitwise*/" instead.


What's next? When writing this do we need the comment shown?

idx++; /* Increment 'idx' */

just because it might confuse a beginner?


No, because "idx++;" is unambiguous.

The problem with "if (a & b)" is that it's as likely to be a newbie
mistake (using "&" where "&&" is correct) as a deliberate use of
bitwise-and. I'd rather add a comment than risk having the next
maintainer of the code (who may not be as comfortable with C as I am)
"correct" the "&" to "&&".
You, the developer must write the code you intend to write. Why
should I not believe you meant bit-AND if you write?

if (reg_a_bits & reg_a_field_mask)


If the variables are called "reg_a_bits" and "reg_a_field_mask", it's
not as much of a problem. If they're called "a" and "b" -- well, they
probably shouldn't be unless it's a toy example.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #26

P: n/a
Keith Thompson <ks***@mib.org> wrote in
news:ln************@nuthaus.mib.org:

[snip]
The problem with "if (a & b)" is that it's as likely to be a newbie
mistake (using "&" where "&&" is correct) as a deliberate use of
bitwise-and. I'd rather add a comment than risk having the next
maintainer of the code (who may not be as comfortable with C as I am)
"correct" the "&" to "&&".


In my world of microcontrollers and drivers, & is more common than &&.
You, the developer must write the code you intend to write. Why
should I not believe you meant bit-AND if you write?

if (reg_a_bits & reg_a_field_mask)


If the variables are called "reg_a_bits" and "reg_a_field_mask", it's
not as much of a problem. If they're called "a" and "b" -- well, they
probably shouldn't be unless it's a toy example.


So the real fix might better to continue to write C without junk comments
but to pick variable names that have meaning? I'm all for that.

--
- Mark ->
--
Nov 14 '05 #27

P: n/a
> > > if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));

Summary: Operator precedence governs the meaning of an
expression with multiple operators, but does not control
the order in which the operands are evaluated.


Finally a sensible answer in this thread. A corollary is: If you
want to use complex logical expressions, parenthise them so there
is NO DOUBT, NO DOUBT WHATSOEVER, what they mean. You will save a
lot of headaches, both your own and others.


(((((How) (would) (that) (help))?) (The (expressions (
((A || B) && C)
(and)
(A || (B && C))
) (have) ((the) (same) ((order) (of) (evaluation))).)
((There) (was) (never) ((any) (doubt) (about) (((the) (meaning))
(of) ((the) (expression)))))).
Nov 14 '05 #28

P: n/a
Mark A. Odell wrote:
Robert Bachmann <Ro*************@rbdev.net> wrote in
When writing something like "if (a & b)" it is a good idea to
write "if (a & b) /*bitwise*/" instead. What's next? When writing this do we need the comment shown?
idx++; /* Increment 'idx' */
just because it might confuse a beginner?

No. My point was that someone (a new code maintainer for example)
who reads code like "if (a & b)" can be in doubt that I really
wanted to bitwise-and "a" and "b".

I've often seen code like "if (a & b)" where the developer
actually should have written "if (a && b)".
So it always attracts my attention when I see code like "if (a & b)".
You, the developer must write the code you intend to write. Yes, but nobody is perfect :-)
Why should I not believe you meant bit-AND
if you write?
if (reg_a_bits & reg_a_field_mask)

If I would have written "if (reg_a_bits & reg_a_field_mask)"
it should be obvious to anyone that I really liked to bitwise-and
some bits with some mask.
In case "if (a & b)" it is not.
So picking up good (meaningful) variable names (as you already said)
is probably a better solution.

-rb
--
Ro*************@rbdev.net
Nov 14 '05 #29

P: n/a
Robert Bachmann wrote:
Keith Thompson wrote:
If I saw code that used "if (a & b)", my first assumption would be
that it was a typo for "if (a && b)", and my second would be that
the author really intended to test the bitwise "and" of a and b.


When writing something like "if (a & b)" it is a good idea to
write "if (a & b) /*bitwise*/" instead.

On the other hand it looks a little bit funny to me, just like
some beginner who writes "int i; /*an integer variable*/" ;-)

So I for myself always use "if (a bitand b)" instead of
"if (a & b)" (after including <iso646.h> of course),
because with this notation it should be obvious to see that I
did *really* mean & and not &&.


I rarely use the ISO646 stuff, because it seems to bring out the
worst in diehard key savers. When I do, I would prefer to use
'and' for &&, and just & for the bitwise stuff. What I really
want out of ISO646 is and, or, xor, not. These make code much
more readable. They also help to enforce minimum intersymbol blank
standards.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #30

P: n/a
Old Wolf wrote:
> if(expr("1st",1) || expr("2nd",0) && expr("3rd",1));

Summary: Operator precedence governs the meaning of an
expression with multiple operators, but does not control
the order in which the operands are evaluated.


Finally a sensible answer in this thread. A corollary is: If you
want to use complex logical expressions, parenthise them so there
is NO DOUBT, NO DOUBT WHATSOEVER, what they mean. You will save a
lot of headaches, both your own and others.


(((((How) (would) (that) (help))?) (The (expressions (
((A || B) && C)
(and)
(A || (B && C))
) (have) ((the) (same) ((order) (of) (evaluation))).)
((There) (was) (never) ((any) (doubt) (about) (((the) (meaning))
(of) ((the) (expression)))))).


Not so.

A B Eval ((A || B) && C) Eval (A || (B && C))
== == =================== ====================
0 0 A B done=0 A B done=0
0 1 A B C done=C A B C done=C
1 0 A C done=C A B done=0
1 1 A C done=C A done=1

If I have made no mistakes. At any rate, the expression values
and side effects are different.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #31

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
Old Wolf wrote: <snip>
(((((How) (would) (that) (help))?) (The (expressions (
((A || B) && C)
(and)
(A || (B && C))
) (have) ((the) (same) ((order) (of) (evaluation))).)
((There) (was) (never) ((any) (doubt) (about) (((the) (meaning))
(of) ((the) (expression)))))).


Not so.

A B Eval ((A || B) && C) Eval (A || (B && C))
== == =================== ====================
0 0 A B done=0 A B done=0
0 1 A B C done=C A B C done=C
1 0 A C done=C A B done=0

^^^^^^^^^^ 1 1 A C done=C A done=1

If I have made no mistakes.
Maybe it's me who is mistaken, but shouldn't the marked (^^^)
line read: A done=1 (just like the one below it)?
At any rate, the expression values
and side effects are different.


However, your claim is of course correct.

Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.eskimo.com/~scs/C-faq/top.html
acllc-c++ faq : http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

Nov 14 '05 #32

P: n/a
In <40**********@mindspring.com> pete <pf*****@mindspring.com> writes:
Dan Pop wrote:

In <40***********************@newsreader02.highway.te lekom.at> Robert Bachmann <Ro*************@rbdev.net> writes:
>Keith Thompson wrote:
>> If I saw code that used "if (a & b)", my first assumption would be
>> that it was a typo for "if (a && b)", and my second would be that the
>> author really intended to test the bitwise "and" of a and b.
>
>When writing something like "if (a & b)" it is a good idea to
>write "if (a & b) /*bitwise*/" instead.
>On the other hand it looks a little bit funny to me, just like
> some beginner who writes "int i; /*an integer variable*/" ;-)


The real solution is to write it as:

if ((a & b) != 0) ...

No silly comments needed to remove any doubt WRT your real intentions.
It is seldom a good idea to skip the explicit comparison.


I believe that you're implying that it's a good idea
to skip the explicit comparison of the result of a logical operation.

You wouldn't write
if ((a && b) != 0)

right ?


Right. When dealing with a logical expression, the explicit comparison
of the result is pointless, because the intent is obvious. Ditto for
numeric variables that are used as flags (conceptually booleans), where
the intent is equally obvious. E.g. I would write:

int i, access_ok = 0;
...
if (i != 0) /* do this */ ;
if (access_ok) /* do that */ ;

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #33

P: n/a
Dan Pop wrote:
When dealing with a logical expression, the explicit comparison
of the result is pointless, because the intent is obvious. Ditto for
numeric variables that are used as flags (conceptually booleans),
where the intent is equally obvious. E.g. I would write:

int i, access_ok = 0;
...
if (i != 0) /* do this */ ;
if (access_ok) /* do that */ ;


Thank you.

--
pete
Nov 14 '05 #34

P: n/a
Old Wolf <ol*****@inspire.net.nz> spoke thus:
(((((How) (would) (that) (help))?) (The (expressions (
((A || B) && C)
(and)
(A || (B && C))
) (have) ((the) (same) ((order) (of) (evaluation))).)
((There) (was) (never) ((any) (doubt) (about) (((the) (meaning))
(of) ((the) (expression))))))


Was that intended to resemble (horrible) Lisp code? ;D

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #35

This discussion thread is closed

Replies have been disabled for this discussion.