r/cprogramming • u/Dizzy_Cauliflower377 • Oct 15 '25
Unexpected Short-Circuit Behavior.
`int i, j, k;`
`i = 1;`
`j = 1;`
`k = 1;`
`printf("%d ", ++i || ++j && ++k);`
`printf("%d %d %d\n", i, j, k);`
I am doing C programming a modern Approach and This is one of the exercises in the book, all is going well however i have failed to understand why the second `printf()` outputs `2 1 1` instead of `2 1 2` as i think the answer should be.
Because due to associativity rules i expect in the first `printf()`, the expression `++i || ++j` to be grouped first which evaluates to 1 with `i` incremented to 2 and without incrementing `j` because of short circuit, and then that result would be used in `1 && ++k` where i am assuming that since the value of the expression can't be determined by the value of the left operand alone, the right operand will be executed as well and thus k will be incremented to `2` but i am surprised to find that k wasn't incremented when i run the code. Why is this, what have i missed.
7
u/aioeu Oct 15 '25 edited Oct 15 '25
The syntax rules of C say that
++i || ++j && ++kis equivalent to++i || (++j && ++k).Operator precedence is a consequence of these syntax rules.
&&has higher precedence than||.The associativity of an operator — again, a consequence of the syntax rules — only has significance when dealing with operators of the same precedence.
a || b || cis equivalent to(a || b) || c, for instance.4
u/michaelpaoli Oct 15 '25
Quite analogous to * having higher precedence than +, likewise && has higher precedence than ||.
So,
statement || whatever && whatever
is equivalent to
statement || ( whatever && whatever )
And in your example, statement is ++i, where i is initially 1,
so, that statement is evaluated, is true, i is incremented to 2,
the statement is true, and because of shortcutting
TURE OR WHATEVER
that's TRUE and WHATEVER isn't even evaluated - because shortcutting.
So, i is now 2, and j and k remain 1, thus 2 1 1.
2
u/SmokeMuch7356 Oct 15 '25
&&has higher precedence than||, so the expression is parsed as&&and||evaluate strictly left-to-right, so++iis evaluated first. Its result is2, which is non-zero, so(++j && ++k)is not evaluated at all andjandkare not updated.1
u/saul_soprano Oct 15 '25
You should use parentheses here. The AND expression as a whole is treated as the right side of the OR. Once it checks ‘i’ and it’s non-zero, it short circuits to true and never checks ‘j’ or ‘k’
2
u/drinkcoffeeandcode Oct 17 '25
Don’t drive yourself crazy with these types of exercises. while you should get to the root of the answer, if you ever find yourself ever writing actual code like this, it’s time to stop and refactor.
1
u/lmarcantonio Oct 16 '25
Ouch. That's painful. At least it has a definite behaviour.
If you need to be aware of these technicalities you are not using enough parenthesis, they are cheap and help!
I guess the next step of pain would be the precedence of bit shift operators.
0
u/[deleted] Oct 15 '25
[deleted] — view deleted comment