how is x&&y||z evaluated?
Asked Answered
A

8

6

Given

int x=1,y=2,z;

Could you explain why the result for:

x && y || z 

is 1?

x && y = 1
x && y || z = 1
Articulator answered 1/9, 2011 at 8:58 Comment(10)
What the hell is the bounty for? Does the question really remain unsatisfactorily answered?Mcfall
Whenever you are unsure whether the code really does what you intended it to do, use brackets. They make the code more readable. It is not "cool" to stuff everything you can into a single statement that can only be parsed when you know ever corner of the language.Fredrika
Re: "What the hell is the bounty for?" -- Often people offer a bounty on satisfactorily answered questions as a means to provide an additional reward to the answerer. That is explicitly allowed, though the person offering the bounty still has a waiting period before they can award it.Wonderment
@mootinator: that may be, but I thought this wasn't the kind of question... :)Mcfall
@mootinator: It also turns out that the person offering the bounty is an answerer :))Mcfall
@ArmenTsirunyan Judging from the upvotes it could be this => meta.stackexchange.com/questions/105275/… although that answer isn't really all that good. Looks fishy to me.Wonderment
Offering a bounty is a really lame way to prevent your question from being closed for being a duplicate/off-topic/etc... This is the most likely reason, I think...Electrolyze
@R.. I don't believe so, because the OP isn't the one offering the bountyMcfall
@PaulPRO: Please stop offering bounties on questions for no apparent reason.Plage
In C (I don't know if it's the same in C++), the result of logical operations (!, &&, ||) is a int type with value 0 or 1Kolnick
M
20
x && y || z 

is equivalent to

(x && y) || z

if x=1 and y=2 then x&&y is 1 && 2 which is true && true which is true.

true || z 

is always true. z isn't even evaluated

Mcfall answered 1/9, 2011 at 9:3 Comment(0)
Y
6

x && y || z => (x && y) || z => 1 || z => 1

Yuonneyup answered 1/9, 2011 at 9:1 Comment(0)
B
5
(bool)1 = true
(bool)2 = true

Uninitialized int refers to data that was saved in memory, where it is placed on stack... and it rarely is 0x00000000, and even if it was, true || false = true.

Booboo answered 1/9, 2011 at 9:0 Comment(0)
P
5

The && operator has higher precedence than the || operator. See, e.g., this operators precedence table, numbers 13 and 14.

Your example evaluates as (x && y) || z. Thanks to the short circuiting rule, z is never evaluated because the result of x && y is already true.

Pact answered 1/9, 2011 at 9:3 Comment(1)
+1 for mentioning short-circuiting. I think that's the key piece here.Giacomo
B
4

You can think of x && y || z as equivalent to:

int func(int x, int y, int z) {
  if (x) {
    if (y) {
      return true;
    }
  }
  if (z) {
    return true;
  }
  return false;
}

Since both x and y are fixed to be non-zero values the first return statement is always hit.

On IA32, without optimisation x && y || z becomes:

        movl    $1, 28(%esp)        ; store 1 in x (on stack)
        movl    $2, 24(%esp)        ; store 2 in y (on stack)
        cmpl    $0, 28(%esp)        ; compare x to 0
        je      .L6                 ; if x is 0 jump to L6
        cmpl    $0, 24(%esp)        ; compare y to 0
        jne     .L7                 ; if y is 0 jump to L7
.L6:                                ; We only get to L6 if (x && y) was false
        cmpl    $0, 20(%esp)        ; compare z to 0
        je      .L8                 ; if z is 0 jump to L8
.L7:                                ; We get to this label if either (x && y) was true
                                    ; or z was true
        movl    $1, %eax            ; copy 1 into register eax, the result
        jmp     .L9                 ; jump unconditionally to L9
.L8:                                ; We only get here if both (x && y) and z are false
        movl    $0, %eax            ; copy 0 into register eax, the result
.L9:

And func becomes:

        cmpl    $0, 8(%ebp)        ; compare first argument (x) with 0
        je      .L2                ; jump to L2 if it is
        cmpl    $0, 12(%ebp)       ; compare second argument (y) with 0
        je      .L2                ; jump to L2 if it is
        movl    $1, %eax           ; store 1 for the return value (via register eax)
        jmp     .L3                ; jump to L3 (done, return to caller)
.L2:                               ; if we hit this label both x and y were false
        cmpl    $0, 16(%ebp)       ; compare third argument (z) with 0
        je      .L4                ; if it is 0 jump to L4
        movl    $1, %eax           ; store 1 in register eax, which is the return value
        jmp     .L3                ; jump to L3 (return to caller)
.L4:                               ; if we get here x, y and z were all 0
        movl    $0, %eax           ; store 0 in eax to return false
.L3:

With optimizations enabled func() looks even more like the expression (the return value only gets loaded from one place, although it's obscured by x86-isms), but the expression x && y || z basically disappears since the compiler is able to deduce its value at compile time.

Breton answered 23/9, 2011 at 21:39 Comment(0)
F
1

Because x && y is evaluated as (x != 0) && (y != 0), which is equivalent with 1 && 1 resulting 1. And 1 || 0 is 1, no matter what y value is.

Faceoff answered 1/9, 2011 at 9:2 Comment(0)
C
0

The && operator has higher precedence than the || operator

Chancellorship answered 26/9, 2011 at 6:55 Comment(0)
P
0

There are 2 components here:

  1. Precedence
  2. Short-circuitry

If it helps you remember, in terms of mathematical operators, || can be replaced with the plus sign "+", which consists of 2 bars and as && can be replaced with a "." and has the multiplication's precedence over the "+" :-)

In C++ and C, when a boolean expression is being evaluated and the result can logically be inferred from a certain term, the following terms do not get evaluated: false && (expr2) is false AND expr2 does not get evaluated. true || (expr3) is true AND expr3 does not get evaluated.

I hope this helps =)

Proteus answered 26/9, 2011 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.