Background
Operator precedence was introduced in C to control the order of evaluation in mathematical and logical expressions. Even though mathematical operators have historically expected precedence (as in algebra), the emergence of many new operators (logical, bitwise, assignment, etc.) has complicated the picture. To reduce the likelihood of errors and enhance readability, an official list of operator precedence and associativity was introduced.
Problem
Due to the larger number of operators and their different natures (arithmetic, comparisons, assignments, logical, indexing), ambiguities arise when forming complex expressions. A wrong understanding of the order of operations leads to logical errors and not always obvious bugs, especially when combining bitwise and logical operators, pointers, increments, and the ternary operator.
Solution
Example code:
#include <stdio.h> int main() { int a = 1, b = 2, c = 3, d; d = a + b * c; // b*c is evaluated first: d = 1 + (2*3) = 7 printf("%d\n", d); d = a + b << 1; // a + b = 3, then 3 << 1 (6) printf("%d\n", d); d = a < b ? a++ : b++; printf("%d\n", d); // a < b is true => d = a (1), a will increase afterwards }
Key features:
What result will the expression x = y > z ? y : z; give if parentheses are forgotten?
Answer: The ternary operator ?: has lower precedence than >. First, (y > z) is evaluated, and then the selection is made between y and z. However, if combined with assignment, unexpected effects can occur. It is better to always use parentheses x = (y > z) ? y : z;.
*What result will the expression p++ give and why?
Answer: The post-increment operator (++) has higher precedence than dereferencing (*), so *p++ becomes *(p++): first, p is used and incremented, only then dereferenced, which can differ from *++p (dereferencing after increment).
Why doesn’t the expression a & b == c work as expected?
Answer: The operator == has higher precedence than &, so the expression is analyzed as a & (b == c), not (a & b) == c, leading to unexpected results. Parentheses are needed for the desired logic.
if ((a & b) == c) { ... }
Negative case
When optimizing code, a programmer combined multiple operators without parentheses: if( mask & flag == 0 ) ..., resulting in incorrect logic and leading to system failure.
Pros:
Cons:
Positive case
Using explicit grouping: if( (mask & flag) == 0 ) ..., logic is transparent, flags are easy to change.
Pros:
Cons: