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
9  
mistake in the original design back in C –  ratchet freak Apr 11 '13 at 8:43
6  
@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 tour page says, "It's not a discussion forum. There's no chit-chat." –  gnat Apr 11 '13 at 9:06
6  
@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
5  
@Dunk: The common "by hunch" approach is [arithmetics] [logic operator] [arithmetics]. Most programmers don't create a mess of parentheses like if(((x+getLowX()) < getMinX) || ((x-getHighX())>getMaxX()))) - most will assume precedence of arithmetics over logics and write if( ( x + getLowX() < getMinX ) || ( x - getHighX() > getMaxX() )) assuming precedence of + above <. Now intuitively if( x ^ getMask() != PATTERN ) should behave the same, XOR being arithmetic operator. The fact it's interpreted as if( x ^ ( getMask() != PATTERN ) ) is completely counter-intuitive. –  SF. Apr 12 '13 at 8:03

2 Answers 2

up vote 41 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
2  
@MasonWheeler: Can you find a Raspberry Pi or Arduino for $0.50 in quantity 1000? –  supercat Jul 8 at 20:20

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

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.