How C Operator Precedence Breaks Your Code (And How to Fix It)

3

You write what you mean. The compiler reads what it wants.

If you have ever stared at a line of C code, convinced it was doing one thing, only to watch it do something else entirely, you have met operator precedence. It is not a bug. It is a feature of the language that bites even seasoned developers.

Take this simple arithmetic:

x=5+3*6;

Math class says add first. C says no. Multiplication and division sit on a higher tier than addition and subtraction. The compiler multiplies 3 by 6 first. Then it adds 5. X gets 23. Not 48. You just lost points on a quiz. Or worse, a production deployment.

The confusion deepens when you mix operators with syntax.

Look at this declaration:

char *a[10];

Is a a pointer to an array of 10 characters? Or is it an array of 10 pointers to characters?

Without knowing the specific precedence rules, you are guessing. In C, brackets [] bind tighter than pointers *. So this is an array of 10 pointers to characters.

This matters because C does not parse like English. It parses like a rigid hierarchy.

You can write code that looks right but fails silently because of precedence.

Consider pointer arithmetic mixed with structure access.

*p.i = 10;

This does not work as expected. The dot operator . has higher precedence than the dereference operator *. The compiler tries to access member i of the object pointed to by p before dereferencing p. But p is a pointer, not a struct. The compiler chokes. Or worse, it interprets memory in a way that corrupts data.

You have to force the issue.

(*p).i = 10;

Parentheses win. Always.

The Hierarchy of Operators

Kernighan and Ritchie, the architects of C, laid out the precedence in their classic text. The table below shows the order. Top line is highest. Bottom is lowest.

  1. Parentheses () and Subscripting []
    • Left to right.
  2. Unary Operators ++, --, +, -, !, ~, (type), * (dereference), & (address), sizeof
    • Right to left.
  3. Multiplicative *, /, %
    • Left to right.
  4. Additive +, -
    • Left to right.
  5. Shift <<, >>
    • Left to right.
  6. Relational <, <=, >, >=
    • Left to right.
  7. Equality ==, !=
    • Left to right.
  8. Bitwise AND &
    • Left to right.
  9. Bitwise XOR ^