Warum haben bitweise Operatoren eine niedrigere Priorität als Vergleiche?

63

Könnte jemand erklären, warum Vergleichsoperatoren (==,! =, <,>, <=,> =) In einer Reihe der beliebtesten Sprachen (siehe Hinweis unten) eine höhere Priorität haben als bitweise Operatoren (&, |, ^) , ~)?

Ich glaube nicht, dass ich jemals auf eine Verwendung gestoßen bin, bei der dieser Vorrang natürlich wäre. Es ist immer so was wie:

  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

Die Fälle, in denen ich verwenden würde:

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

sind in der Nähe von nicht vorhanden.

Was war die Motivation der Sprachdesigner, sich für einen solchen Vorrang der Operatoren zu entscheiden?


Zum Beispiel sind alle Sprachen mit Ausnahme von SQL in den Top-12-Sprachen so wie in der Beliebtheitsliste für Programmiersprachen auf langpop.com: C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL, Ruby, Shell, Visual Basic.

SF.
quelle
16
Fehler im ursprünglichen Design zurück in C
Ratschen
7
@ Gnat, was ist der Grund für diese Beschwerde? Das OP sagte nicht "alles", sondern nur "ein Bündel der beliebtesten Sprachen". Und die überwiegende Mehrheit folgt dieser Reihenfolge. In dieser Tabelle gibt es nur eine der Top 12 (SQL) nicht: langpop.com
3
@ dan1111 Punkt ist natürlich, den Antwortenden zu helfen, die gestellte Frage besser zu verstehen und bessere Antworten zu geben. Sie sehen, dies ist kein Ort für The Guessing Game - oder, wie auf der Tour- Seite steht: "Es ist kein Diskussionsforum. Es gibt keinen Chat."
Mücke
7
@gnat, ich stimme Ihrer Besorgnis über Ratespiele zu, aber ich glaube nicht, dass dies qualifiziert ist, wenn fast jede populäre Sprache das beschriebene Verhalten aufweist.
5
@Dunk: Der übliche "by hunch" -Ansatz ist [arithmetics] [logic operator] [arithmetics]. Die meisten Programmierer erzeugen kein Durcheinander von Klammern wie if(((x+getLowX()) < getMinX) || ((x-getHighX())>getMaxX())))- die meisten nehmen an, dass Arithmetik Vorrang vor Logik hat, und schreiben if( ( x + getLowX() < getMinX ) || ( x - getHighX() > getMaxX() )) unter der Voraussetzung, dass Vorrang vor der +obigen <. Nun if( x ^ getMask() != PATTERN ) sollte sich intuitiv das gleiche verhalten, wobei XOR der arithmetische Operator ist. Die Tatsache, dass es als if( x ^ ( getMask() != PATTERN ) )völlig kontraintuitiv interpretiert wird.
SF.

Antworten:

72

Sprachen haben das von C kopiert, und für C erklärt Dennis Ritchie , dass es anfangs in B (und vielleicht in frühem C) nur eine Form gab, &die je nach Kontext eine bitweise und / oder eine logische Form hatte . Später bekam jede Funktion ihren Operator: &für die bitweise und &&für die logische. Dann fährt er fort

Ihre verspätete Einführung erklärt eine Ungleichheit der Vorrangregeln von C. In B schreibt man

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

zu überprüfen, ob agleich bund cungleich Null ist; In einem solchen bedingten Ausdruck ist es besser, &wenn er eine niedrigere Priorität hat als ==. Wenn man von B nach C konvertiert, möchte man in einer solchen Aussage &durch ersetzen &&; Um die Konvertierung weniger schmerzhaft zu gestalten, haben wir uns entschlossen, den Vorrang des &Operators im Verhältnis zum Operator beizubehalten ==und lediglich den Vorrang von &&geringfügig zu trennen &. Heutzutage scheint es vorzuziehen gewesen zu sein, die relativen Prioritäten von &und zu verschieben ==und damit ein gemeinsames C-Idiom zu vereinfachen: Um einen maskierten Wert gegen einen anderen Wert zu testen, muss man schreiben

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

wo die inneren Klammern erforderlich sind, aber leicht vergessen werden.

Ein Programmierer
quelle
1
Würde das nicht scheitern, wenn c=2Oder dazu a==bführen würde ~0und nicht 1?
SF.
Anscheinend gibt a == b 0 oder 1 zurück, siehe cm.bell-labs.com/cm/cs/who/dmr/kbman.html .
AProgrammer
Überprüfen Sie den Verweis in der Antwort und lesen Sie den vorhergehenden Text.
SShaheen
1
@MasonWheeler: Insbesondere in eingebetteten Systemen ist es manchmal erforderlich, funktionsähnliche Makros zu verwenden (in einigen Fällen bieten sie eine um Größenordnungen bessere Leistung als Inline-Funktionen und in einigen eingebetteten Systemen können sie kritisch sein). Eine Variablendeklaration innerhalb solcher Makros ist nicht möglich; Die Verwendung einer globalen Variablen in einem Makro mag funktionieren, scheint aber sehr schwierig zu sein.
Supercat
6
@ MasonWheeler: Kannst du einen Raspberry Pi oder Arduino für 0,50 USD in einer Menge von 1000 finden?
Supercat
7

Bitweise Operatoren sind konzeptionell und optisch mit logischen Operatoren verwandt, was wahrscheinlich erklärt, warum sie in der Ranglistentabelle nahe beieinander liegen. Vielleicht könnte man sogar argumentieren, dass es verwirrend wäre, &höher zu sein als ==, &&aber niedriger zu sein ==.

Sobald ein Präzedenzfall (!) Festgelegt wurde, war es wahrscheinlich aus Gründen der Konsistenz für andere Sprachen besser, diesem zu folgen.

Ich stimme Ihnen jedoch eher zu, dass dies nicht optimal ist. In der Praxis ähneln Bitoperatoren eher mathematischen als logischen Operatoren, und es wäre besser, sie vorrangig mit den mathematischen Operatoren zu gruppieren.


quelle