Search code examples
coperator-precedence

Operator precedence in C (!= and |)


I recently corrected a bug in a C program where I had:

if (foobar != FOO | BAR | BAZ)

The correct code is

if (foobar != (FOO | BAR | BAZ))

According to the C operator precedence it is clear that != has precedence over |.

My question is why it is like this and not the other way around? From my experience I will often use either a == b || a == c or d == (a | b | c), but never a == b | c == d.

What is the logic behind this choice?


Solution

  • It has historical reasons, quote from Dennis Ritchie:

    “Early C had no separate operators for & and && or | and ||. Instead it used the notion (inherited from B and BCPL) of ‘truth-value context': where a Boolean value was expected, after ‘if‘ and ‘while‘ and so forth; the & and | operators were interpreted as && and || are now; in ordinary expressions, the bit-wise interpretations were used. It worked out pretty well, but was hard to explain. (There was the notion of ‘top-level operators’ in a truth-value context.) “The precedence of & and | were as they are now.

    Primarily at the urging of Alan Snyder, the && and || operators were added. This successfully separated the concepts of bit-wise operations and short-circuit Boolean evaluation. However, I had cold feet about the precedence problems. For example, there were lots of programs with things like: if (a==b & c==d) …

    “In retrospect it would have been better to go ahead and change the precedence of & to higher than ==, but it seemed safer just to split & and && without moving & past an existing operator.”