0

Please explain the output:

#include<iostream.h>
int main()
{
    int i= -3, j=2, k=0, m;
    m = ++i || ++j && ++k;
    cout<< i <<" " << j << " " << k <<" "<<m;
    return 0;
}

OUTPUT : -2 2 0 1

Here's what I thought: (++i || ++j) && (++k) //Considering the precedence order ++i becomes -2 so first part of OR true, so it won't check 2nd part.
(Thanks Joachim Pileborg for telling me the short circuit evaluation)

So overall, first part of AND is true. But that is not enough for statement to be true, 2nd part must be true to. So ++k makes k = 1 Here's where I get it wrong. Why is k not increasing?

whereas, in this case:

#include<iostream.h>
int main()
{
    int i= -1, j=2, k=0, m;
    m = ++i || ++j && ++k;
    cout<< i <<" " << j << " " << k <<" "<<m;
    return 0;
}

OUTPUT: 0 3 1 1

I got this one too considering short circuit evaluation.

lazygeek
  • 51
  • 1
  • 7
  • 3
    What did you not understand ? What did you expect ? – Caduchon Nov 03 '14 at 08:07
  • 7
    Remember that the logical operators uses [short-circuit evaluation](http://en.wikipedia.org/wiki/Short-circuit_evaluation). – Some programmer dude Nov 03 '14 at 08:08
  • If in doubt, use brackets. Relying on operator precidence is all well and good, but all it takes is one mistake. In situations like this I prefer to define the 'order' of execution explicitly (precidence through`()`'s) – Baldrickk Nov 03 '14 at 10:20

3 Answers3

1

Let's start with this code snippet

#include<iostream.h>
int main()
{
    int i= -3, j=2, k=0, m;
    m = ++i || ++j && ++k;
    cout<< i <<" " << j << " " << k <<" "<<m;
    return 0;
}

It is obvious that m will be have a boolean value converted to int. As ++i is equal to -2 that is unequal to zero then all other expressions will not be evaluated because it is already known that the whole expression is equal to true. So after statement

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

m is equal to 1 and i is equal to -2 All other variables were not changed.

In this code snippet

#include<iostream.h>
int main()
{
    int i= -1, j=2, k=0, m;
    m = ++i || ++j && ++k;
    cout<< i <<" " << j << " " << k <<" "<<m;
    return 0;
}

++i will be equal to 0. So the right operand of operator || will be evaluated. This operand is

++j && ++k

As ++j will be equal to 3 and is not equal to 0 then ++k also will be evaluated and will be equal to 1. As the both operands of operator && is not equal to zero then the result is equal to true

Thus you will get i == 0, j == 3, k == 1, m == 1.

From the C++ Standard

5.14 Logical AND operator

1 The && operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

5.15 Logical OR operator

1 The || operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

In logical expressions, such as: ... || ... && ... C++ can omit executing statements that would not change the output value of expression. For example: if it computes first value and it's output is not equal to 0, then expression: true || ... && ... is always true, therefore execution of further expressions is not necessary

0

Below is your second case:-

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

In

( cond1 || cond2) 

expression if cond1 is true then compiler does not go on to check for cond2. It will evaluate cond2 only if cond1 returns false.

So, in second ++i makes first expression to be false and forces compiler to go on to evaluate further whereas in first case first expression returns true.

ravi
  • 10,994
  • 1
  • 18
  • 36