behavior of || operator

M

Mark

Hello,

#define ATTACH 1
#define DETACH 2

#define DIRECTION_INGRESS 1 /* Incoming */
#define DIRECTION_EGRESS 2 /* Outgoing */



if ((action != ATTACH) || (action != DETACH))

puts("invalid action");

if ((dir != DIRECTION_INGRESS) || (dir != DIRECTION_EGRESS))
puts("invalid direction");



I appears that condition within if() is verified for being TRUE or FALSE,
and it is sufficient to have just one operand of || operator to return TRUE
in order for the whole expression yield TRUE result.



For example, if action = 1, then (action != ATTACH) becomes FALSE, then
(action != DETACH) is evaluated and it will return TRUE, thus making the
statement within if() TRUE. And this is wrong behavior, given that I need to
have actoni be either 1 or 2.



To make it right, || must be replaced with &&.



Is my reasoing above correct and valid?



Thanks.



Mark.
 
S

Stefan Ram

Mark said:
I appears that condition within if() is verified for being TRUE or FALSE,

The if-expression is /evaluated/. The first substatement
is executed if the expression compares unequal to 0.

The || operator yields 1 if either of its operands compare
unequal to 0; otherwise, it yields 0.
 
J

James Kuyper

Hello,

#define ATTACH 1
#define DETACH 2

#define DIRECTION_INGRESS 1 /* Incoming */
#define DIRECTION_EGRESS 2 /* Outgoing */



if ((action != ATTACH) || (action != DETACH))

puts("invalid action");

This code is equivalent to:

if(action != ATTACH)
puts("invalid action");
else if(action != DETACH)
puts("invalid action");

Since ATTACH != DETACH, this is, in turn equivalent to:
puts("invalid action");

I don't think that's what you want to do.
if ((dir != DIRECTION_INGRESS) || (dir != DIRECTION_EGRESS))
puts("invalid direction");



I appears that condition within if() is verified for being TRUE or FALSE,
and it is sufficient to have just one operand of || operator to return TRUE
in order for the whole expression yield TRUE result.

Yes, that's what || means: it either operand is true, the whole
expression is true.
For example, if action = 1, then (action != ATTACH) becomes FALSE, then
(action != DETACH) is evaluated and it will return TRUE, thus making the
statement within if() TRUE. And this is wrong behavior, given that I need to
have actoni be either 1 or 2.



To make it right, || must be replaced with &&.

Yes:
if ((action != ATTACH) && (action != DETACH))
puts("invalid action");

is equivalent to:

if(action != ATTACH)
{
if(action != DETACH)
puts("invalid action");
}

Which seems a better fit to what I think you want.
 
J

John Gordon

In said:
#define ATTACH 1
#define DETACH 2
if ((action != ATTACH) || (action != DETACH))
puts("invalid action");
I appears that condition within if() is verified for being TRUE or FALSE,
and it is sufficient to have just one operand of || operator to return TRUE
in order for the whole expression yield TRUE result.
To make it right, || must be replaced with &&.
Is my reasoing above correct and valid?

You should use && instead of ||, yes.

But not because of the behavior you describe above; using || is simply
incorrect logic.

No matter what value action has, it will ALWAYS be either unequal to 1 or
unequal to 2. Using || is just wrong. You want to know when it is unequal
to 1 AND unequal to 2.
 
W

Willem

Mark wrote:
) if ((action != ATTACH) || (action != DETACH))
) puts("invalid action");

It looks like you don't understand De Morgan's laws.

In English:
If action is not attach or action is not detach, then it is an invalid
action.

What you wanted to do is this:
If action is not attach or detach, then it is an invalid action.

Which is:
if (!(action == ATTACH || action == DETACH))
puts("invalid action");

Which, according to De Morgan, is equivalent to:
if ((action != ATTACH) && (action != DETACH))
puts("invalid action");


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
G

Gene

Hello,

#define ATTACH           1
#define DETACH           2

#define DIRECTION_INGRESS       1   /* Incoming */
#define DIRECTION_EGRESS        2   /* Outgoing */

if ((action != ATTACH) || (action != DETACH))

    puts("invalid action");

if ((dir != DIRECTION_INGRESS) || (dir != DIRECTION_EGRESS))
    puts("invalid direction");

I appears that condition within if() is verified for being TRUE or FALSE,
and it is sufficient to have just one operand of || operator to return TRUE
in order for the whole expression yield TRUE result.

For example, if action = 1, then (action != ATTACH) becomes FALSE, then
(action != DETACH) is evaluated and it will return TRUE, thus making the
statement within if() TRUE. And this is wrong behavior, given that I needto
have actoni be either 1 or 2.

To make it right, || must be replaced with &&.

Is my reasoing above correct and valid?

Thanks.

Mark.

I think you'll want to read up on De Morgan's laws (and all the rest
of simple Boolean logic, which BTW is normally part of high school
algebra).

If you have a condition "p or q" and want to logically invert it, the
rule is not(p or q) = not p and not q.

In this case I think you're saying "if dir is not equal to either
INGRESS or EGRESS, then it's an error". By De Morgan, this translates
to if "dir is not INGRESS _and_ dir is not EGRESS, it's an error" .
 

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,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top