6

I have a problem with a question in my book:

#include<stdio.h>
void main()
{
    int a=5, b=-7, c=0, d;
    d = ++a && ++b || ++c;
    printf("\n%d%d%d%d",a,b,c,d);
}

The question asks me what is the output of the code. I ran it and the result on the screen is 6-601. I understand why a=6 and b=-6, but I don't understand why c=0 and d=1?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Hoang.T
  • 63
  • 5
  • Your answer got accepted. That's about as much proof as you would need. I sometimes wonder if I'm not overdoing it, when I write an answer like that, and by the time I'm done, someone has written a 'Try this ``' answer that got accepted instead. – GolezTrol Dec 29 '15 at 07:03
  • @GolezTrol I think sir you meant to post this comment under my answer, however, thank you. :) – Sourav Ghosh Dec 30 '15 at 20:36
  • @SouravGhosh Ah, that's where that comment went! I meant to post it under [your question on Meta](http://meta.stackoverflow.com/questions/313420/how-much-explanation-is-good-am-i-overdoing-it), but then I couldn't find it anymore. :) – GolezTrol Dec 30 '15 at 21:07

2 Answers2

16

I believe you already got your answer, but just to elaborate a bit step-by-step, let me add one more clarification here. Firstly, to quote the properties of the && and || operators, from C11 standard, chapter §6.5.13 and §6.5.13, respectively,

(I)

The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. [...] If the first operand compares equal to 0, the second operand is not evaluated.

and

(II)

The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. [...]. If the first operand compares unequal to 0, the second operand is not evaluated.

and they both guarantee left-to-right evaluation. So, comparing your code,

d = ++a && ++b || ++c;

it happens like

d = ((++a && ++b) || ++c );

which evaluates to

d = (( 6 && ++b ) || ++c);

and then

d = ( ( 6 && (-6) ) || ++c); 

Now in above stage, (I) is fulfilled and it comes down to

d = ( 1 || ++c);

Now, following the emphasis, which already meets the (II), so no further evaluation of the RHS operand of || is performed (i.e., ++c is not evaluated), and it appears to be d = 1 and the final result, 1, is stored into d.

That's how, a == 6, b == -6, c == 0 and d ==1.


Having said that, void main() should be changed to int main(void), at least to conform with the standard.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Thank you, your explanation is very clear, but i'm confused between void main() and int main(void), the code above i just copied directly from my book. – Hoang.T Dec 25 '15 at 07:15
  • @Hoang.T there is very good discussion posted [here](http://stackoverflow.com/q/204476/2173917). Do read it. :) – Sourav Ghosh Dec 25 '15 at 07:17
14

The || OR operator is short-circuiting, which means that if the left side is true then the right side is not evaluated. In this case ++a && ++b evaluates to true, so ++c is never run and c keeps its value of zero.

Also since it evaluates to true, this is denoted with 1 which is stored in d.

Any non-zero value is considered to be true and the result of boolean operations is defined to be 0 or 1 as an integer.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74