9 Binary Operator Grammar

Binary operators are those that take two operands, one on the left and one on the right.

All the binary operators in C are syntactically left-associative. This means that op b op c means (a op b) op c. However, the only operators you should repeat in this way without parentheses are ‘+’, ‘-’, ‘*’ and ‘/’, because those cases are clear from algebra. So it is OK to write a + b + c or a - b - c, but never a == b == c or a % b % c. For those operators, use explicit parentheses to show how the operations nest.

Each C operator has a precedence, which is its rank in the grammatical order of the various operators. The operators with the highest precedence grab adjoining operands first; these expressions then become operands for operators of lower precedence.

The precedence order of operators in C is fully specified, so any combination of operations leads to a well-defined nesting. We state only part of the full precedence ordering here because it is bad practice for C code to depend on the other cases. For cases not specified in this chapter, always use parentheses to make the nesting explicit.3

Clean code can depend on this subsequence of the precedence ordering (stated from highest precedence to lowest):

  1. Postfix operations: access to a field or alternative (‘.’ and ‘->’), array subscripting, function calls, and unary postfix operators.
  2. Unary prefix operations.
  3. Multiplication, division, and remainder (they have the same precedence).
  4. Addition and subtraction (they have the same precedence).
  5. Comparisons—but watch out!
  6. Logical operations ‘&&’ and ‘||’—but watch out!
  7. Conditional expression with ‘?’ and ‘:’.
  8. Assignments.
  9. Sequential execution (the comma operator, ‘,’).

Two of the lines in the above list say “but watch out!” That means that the line covers operations with subtly different precedence. When you use two comparison operations together, don’t depend on the grammar of C to control how they nest. Instead, always use parentheses to show their nesting.

You can let several ‘&&’ operations associate, or several ‘||’ operations, but always use parentheses to show how ‘&&’ and ‘||’ nest with each other. See Logical Operators.

There is one other precedence ordering that clean code can depend on:

  1. Unary postfix operations.
  2. Bitwise and shift operations—but watch out!
  3. Conditional expression with ‘?’ and ‘:’.

The caveat for bitwise and shift operations is like that for logical operators: you can let multiple uses of one bitwise operation associate, but always use parentheses to control nesting of dissimilar operations.

These lists do not specify any precedence ordering between the bitwise and shift operations of the second list and the binary operations above conditional expressions in the first list. When they come together, parenthesize them. See Bitwise Operations.


Footnotes

(3)

Personal note from Richard Stallman: I wrote GCC without remembering anything about the C precedence order beyond what’s stated here. I studied the full precedence table to write the parser, and promptly forgot it again. If you need to look up the full precedence order to understand some C code, add enough parentheses so nobody else needs to do that.