Operator precedence (bitwise '&' lower than '==')
Asked Answered
R

3

50

In the C programing language, why do the bitwise operators (& and |) have lower precedence than the equality operator (==)? It does not make sense to me.

Rackley answered 13/1, 2011 at 20:48 Comment(3)
Because that's the way they designed it. Also, parentheses are cheap.Grouch
Why it doesn't make sense to you?Countersink
I got caught out when using the expression if (a & b == c), took me a while to find out why it wasn't working.Rackley
A
55

You need to ask Brian Kernighan or Dennis Ritchie.
From the forum post Operator precedence:

The && and || operators were added later for their "short-circuiting" behavior. Dennis Ritchie admits in retrospect that the precedence of the bitwise operators should have been changed when the logical operators were added. But with several hundred kilobytes of C source code in existence at that point and an installed base of three computers, Dennis thought it would be too big of a change in the C language...

So, that might be a reason? I'm guessing since there are several layers of bitwise precedence (unlike relational comparisons) that it's cruft that's existed since...forever...and just was never corrected.

Abbie answered 13/1, 2011 at 20:55 Comment(2)
That quote is actually misquoted. Dennis Ritchie explains this himself in his paper "Chistory", which you can read here. In my opinion, Ritchie's wording is much better. Ritchie regretted having the precedence as such, but it was made so to have minimal conversion friction from the B language, C's predecessor, when he was first forming the C language. B only supported & on cells and didn't have an explicit boolean operator due to B's lack of a type system. This also explains why "true" means "not 0" -- bitwise AND doesn't always yield a perfect 1.Giffie
But == isn't a short-circuiting operator so why does this answer the question? However, thank you @Qix, because your comment also explains why the bitwise operators all have different (seemingly arbitrary) precedences - they're from B as seen in the B Tutorial Appendix D (a question which had been vexing me). (And my guess is that B did it that way for no other reason than that it is easy to write a recursive descent parser with that kind of expression grammar.)Ladanum
U
19

It doesn't make sense to Dennis Ritchie, either, in retrospect.

&& and || were added to the language after | and &, and precedence was maintained for reasons of compatibility.

Unwitting answered 13/1, 2011 at 20:59 Comment(0)
A
5

I don't have an authoritative answer as to why K&R chose the precedence they did. One example that makes a fair amount of sense would be this one:

if (x == 1 & y == 0) {
    /* ... */
}

Since this is the bitwise AND operator, it uses a non-short-circuiting evaluation mode, as would

if (x == 1 | y == 0) {
    /* ... */
}

use the non-short-circuiting OR operator. This is probably why they chose to have the precedence group this way, but I agree with you that in retrospect it doesn't seem like a good idea.

Allstar answered 13/1, 2011 at 20:52 Comment(5)
This doesn't make any sense. Why would you use the bitwise operator instead of a logical one in this case?Vivisection
@Nathan Fellman- Caladain's answer seems to hit this one on the head.Allstar
Right. The precedence of & and | makes perfect sense as logical operators, but little sense as bitwise operators.Chromatic
Kudos for this awesome non-short-circuiting logical operators usage. Never thought of that.Insightful
@NathanFellman If you really need both aaaa() and bbbb() to run and you like unreadable code, you'd write if (aaaa() == 1 & bbbb() == 0). There really is no other reason.Smedley

© 2022 - 2024 — McMap. All rights reserved.