Why doesn't ++i || ++j && ++k give the expected value

The logical AND operator && has higher precedence than the logical OR operator ||. So the expression is actually parsed as:

++i || (++j && ++k)

++i evaluates to true so the entire right side of the ||, i.e. ++j && ++k, is not evaluated. This results in neither j nor k being incremented.

It can be difficult to remember all the precedence rules, both for yourself and for others who read your code. So when in doubt, use parenthesis to clarify your intentions.


Running with compiler warnings, or a good editor like Atom.io, reveals the problem.

cc -Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c99 -pedantic -g `pkg-config --cflags glib-2.0`   -c -o test.o test.c
test.c:8:30: warning: '&&' within '||' [-Wlogical-op-parentheses]
    printf("%d ", ++i || ++j && ++k);
                      ~~ ~~~~^~~~~~
test.c:8:30: note: place parentheses around the '&&' expression to silence this warning
    printf("%d ", ++i || ++j && ++k);
                             ^
                         (         )
1 warning generated.

It's a precedence issue. Operators in an expression are not evaluated left-to-right but rather in precedence order. ++i || ++j && ++k is being evaluated as ++i || (++j && ++k) because && has a higher precedence than ||.

To avoid these issues, turn on compiler warnings and make it a habit to put parens around anything that might be ambiguous.

Tags:

C