1

The output of the following program is not as i had expected it to be.Please explain it to me how the logical expression works in this program.

#include<stdio.h>
int main()
{
    int i=-3, j=2, k=0, m;
    m = ++i || ++j && ++k;
    printf("%d, %d, %d, %d\n", i, j, k, m);
    return 0;
}

the output i had expected is -2, 3, 1, 1 the output is -2, 2, 0, 1 why are j and k not increamenting

avinash
  • 119
  • 1
  • 7
  • I don't know C but my guess would be that `||` is a shortcircuiting operator and that `-2` evaluates to true when coerced into a boolean. That boolean true then becomes 1 when outputted as a number by the `printf`. – Chris Aug 15 '14 at 15:54
  • 1
    @Chris: That's correct (except that there's no coercion; `&&` and `||` yield a result of type `int` with value `0` or `1`). – Keith Thompson Aug 15 '14 at 15:54
  • 2
    this is an exact duplicate of [Please explain an apparent conflict between precedence of && and || and the actual result of an expression](http://stackoverflow.com/questions/3375041) and the short circuiting is explained in [here](http://stackoverflow.com/questions/628526) – martin Aug 15 '14 at 15:58

4 Answers4

10

since ++i is not zero, and hence true, the evaluation of the statement stops and returns true

ie

true || (++j && ++k)

is always true, and is true without needing to evaluate the bit after the || and hence it wont change j or k

pm100
  • 48,078
  • 23
  • 82
  • 145
  • Small addition: Some compiler options allow to not-shortcircuit, and result in the expected output. Check your specific compiler documentation. – Pieter21 Aug 15 '14 at 15:57
  • there are C compilers that will not short circuit?! - I am very surprised. So much C code depends on this behavior. And humans reading the code would expect it too – pm100 Aug 15 '14 at 15:58
  • @pm100 see [here](http://stackoverflow.com/questions/628526), it is guaranteed – martin Aug 15 '14 at 16:05
  • Should be noted, the purpose of the short-circuit is to save CPU cycles. – Fiddling Bits Aug 15 '14 at 16:09
  • yes - it was, but it is now relied on every where . How often have you seen if(ptr != null && ptr->flag). Without short circuit that code fails – pm100 Aug 15 '14 at 16:36
2

j and k are not incrementing because of short circuit feature of ||. Evaluation of ++i || ++j && ++k stops right after ++i is evaluated to be non-zero (meaning true).

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
2

When you have a boolean expression, a part of it may be sufficient to get the result. For instance, -2 || 3 && 1 is the same as (-2) || (3&&1). So if (-2) yields true, the whole expression yields true, and there is no need to evaluate the rest of the expression. This way, ++j && ++k never gets executed.

You might also want to try this :

#include<stdio.h>
int main()
{
    int i=-3, j=2, k=0, m;
    m = ++j && ++k || ++i;
    printf("%d, %d, %d, %d\n", i, j, k, m);
    return 0;
}
Nelfeal
  • 12,593
  • 1
  • 20
  • 39
1

If I am right (someone correct me if I'm wrong), it evaluates ++i (which returns a non-zero value), so ++i is "true", than the compiler sees ||, with a "true" expression preceding it, so it skips line and returns "true" (1). The program never execute ++j nor ++k.

cedlm
  • 11
  • 1