Perché gli operatori bit a bit hanno priorità inferiore rispetto ai confronti?

61

Qualcuno potrebbe spiegare la logica, perché in un gruppo di più popolari linguaggi (vedi nota sotto) gli operatori di confronto (==,! =, & lt ;, & gt ;, < =, > =) hanno una priorità più alta di quella bit a bit operatori (& amp ;, |, ^, ~)?

Non penso di aver mai incontrato un uso in cui questa precedenza sarebbe stata naturale. È sempre tipo:

  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

I casi in cui vorrei usare:

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

sono vicini a inesistenti.

Qual è stata la motivazione dei progettisti di linguaggi a decidere su tale precedenza degli operatori?

Ad esempio, tutti tranne l'SQL nelle 12 migliori lingue sono come in Programming Language Popularity list su langpop.com : C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL, Ruby, Shell, Visual Basic.

    
posta SF. 11.04.2013 - 10:13
fonte

2 risposte

69

Le lingue lo hanno copiato da C, e per C, Dennis Ritchie spiega che inizialmente, in B (e forse all'inizio di C), esisteva solo una forma & che, a seconda del contesto, eseguiva un bit per bit o uno logico. Successivamente, ogni funzione ha ottenuto il suo operatore: & per bit a bit e && per logico. Quindi continua

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.

    
risposta data 11.04.2013 - 13:21
fonte
7

Gli operatori bit a bit sono correlati agli operatori logici sia concettualmente che in apparenza, il che probabilmente spiega perché sono vicini l'uno all'altro nella tabella di precedenza. Forse si potrebbe anche obiettare che sarebbe confuso per & essere superiore a == , tuttavia avere && essere inferiore a == .

Una volta impostato un precedente di precedenza (!), probabilmente era meglio che altre lingue lo seguissero per coerenza.

Tuttavia, sono tendenzialmente d'accordo con te sul fatto che non è ottimale. In pratica, gli operatori di bit sono più simili a operatori matematici che logici, e sarebbe meglio se fossero raggruppati con gli operatori matematici in precedenza.

    
risposta data 11.04.2013 - 10:50
fonte