Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Could someone explain the rationale, why in a bunch of most popular languages (see note below) comparison operators (==, !=, <, >, <=, >=) have higher priority than bitwise operators (&, |, ^, ~)?

I don't think I've ever encountered a use where this precedence would be natural. It's always stuff like:

  if( (x & MASK) == CORRECT ) ...   // Chosen bits are in correct setting, rest unimportant

  if( (x ^ x_prev) == SET )      // only, and exactly SET bit changed

  if( (x & REQUIRED) < REQUIRED )   // Not all conditions satisfied

The cases where I'd use:

  flags = ( x == 6 | 2 );     // set bit 0 when x is 6, bit 1 always.

are near to nonexistent.

What was the motivation of language designers to decide upon such precedence of operators?


For example, all but SQL at the top 12 languages are like that on Programming Language Popularity list at langpop.com: C, Java, C++, PHP, JavaScript, Python, C#, Perl, SQL, Ruby, Shell, Visual Basic.

share|improve this question
8  
mistake in the original design back in C –  ratchet freak Apr 11 '13 at 8:43
2  
Could you please explain in more details what language are you talking about? Not all of them fit, see: Which programming languages doesn't use operator precedence besides Lisp like languages? "bunch of most popular" somehow doesn't quite cut it –  gnat Apr 11 '13 at 8:45
5  
@gnat, what is the point of that complaint? The OP didn't say "all", just "a bunch of the most popular languages". And the vast majority follow this order. In this table, only one of the top 12 (SQL) doesn't: langpop.com –  dan1111 Apr 11 '13 at 8:59
3  
@dan1111 point is, naturally, to help answerers better understand the question asked and provide better answers. You see, this is not a place for The Guessing Game - or, as about page says, "It's not a discussion forum. There's no chit-chat." –  gnat Apr 11 '13 at 9:06
5  
@gnat, I agree with your concern about guessing games, but I don't think this qualifies when nearly every popular language exhibits the described behavior. –  dan1111 Apr 11 '13 at 11:18
show 9 more comments

2 Answers

up vote 38 down vote accepted

Languages have copied that from C, and for C, Dennis Ritchie explains that initially, in B (and perhaps early C), there was only one form "&" which depending on the context did a bitwise and or a logical one. Later, each function got its operator, & for the bitwise one and && for for logical one. Then he continues

Their tardy introduction explains an infelicity of C's precedence rules. In B one writes

if (a==b & c) ...

to check whether a equals b and c is non-zero; in such a conditional expression it is better that & have lower precedence than ==. In converting from B to C, one wants to replace & by && in such a statement; to make the conversion less painful, we decided to keep the precedence of the & operator the same relative to ==, and merely split the precedence of && slightly from &. Today, it seems that it would have been preferable to move the relative precedences of & and ==, and thereby simplify a common C idiom: to test a masked value against another value, one must write

if ((a&mask) == b) ...

where the inner parentheses are required but easily forgotten.

share|improve this answer
    
Wouldn't that fail if c=2 Or did a==b result in ~0 and not 1? –  SF. Apr 11 '13 at 11:27
    
Seem so, a==b returns 0 or 1, see cm.bell-labs.com/cm/cs/who/dmr/kbman.html. –  AProgrammer Apr 11 '13 at 11:35
    
Check the reference in the answer and read the preceding text. –  SShaheen Apr 11 '13 at 20:14
    
Oh. So the meaning of & changes depending on where you place it. For a=1; b=2; if(a & b){...}` will execute the block, while c = a & b; if(c){...} will consider the condition not satisfied. Big thanks to mr. Richie for fixing that. –  SF. Apr 12 '13 at 8:11
    
Interesting. Having only one operator whose meaning is contextual is really the best way to do it. (integer and integer: bitwise and, boolean and boolean: boolean and; integer and boolean: syntax error). Problem is, C doesn't have a proper boolean type (everything can be a boolean) so this system doesn't work and we're left with the ugly hack of having duplicated operators. And even later C-derived languages that do have a real boolean type don't fix this problem. (Looking at you, C# and Java.) –  Mason Wheeler May 6 '13 at 15:39
show 1 more comment

Bitwise operators are related to logical operators both conceptually and in appearance, which probably explains why they are near each other in the precedence table. Perhaps one could even argue that it would be confusing for & to be higher than ==, yet have && be lower then ==.

Once a precedence precedent (!) was set, it was probably better for other languages to follow it for consistency's sake.

However, I tend to agree with you that this is not optimal. In actual use, bit operators are more like mathematical operators than logical ones, and it would be better if they were grouped with the mathematical operators in precedence.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.