Почему побитовые операторы имеют более низкий приоритет, чем сравнения?

63

Может ли кто-нибудь объяснить обоснование, почему в группе самых популярных языков (см. Примечание ниже) операторы сравнения (==,! =, <,>, <=,> =) Имеют более высокий приоритет, чем побитовые операторы (&, |, ^ ~)

Я не думаю, что я когда-либо сталкивался с использованием, где этот приоритет был бы естественным. Это всегда такие вещи, как:

  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

Случаи, когда я бы использовал:

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

близки к несуществующему.

Какова была мотивация дизайнеров языка, чтобы принять решение о таком приоритете операторов?


Например, все, кроме SQL в топ-12 языков, аналогичны спискам популярности языков программирования на langpop.com: C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL, Ruby, Shell, Visual Basic.

Научная фантастика
источник
16
ошибка в оригинальном дизайне назад в C
храповик урод
7
@gnat, в чем смысл этой жалобы? ОП не сказал «все», просто «группа самых популярных языков». И подавляющее большинство следуют этому порядку. В этой таблице только один из лучших 12 (SQL) не имеет: langpop.com
3
@ dan1111, естественно, состоит в том, чтобы помочь ответчикам лучше понять заданный вопрос и дать более качественные ответы. Видите ли, это не место для «Угадайки» - или, как говорится на странице тура : «Это не дискуссионный форум. Там нет болтовни».
комнат
7
@gnat, я согласен с вашей заботой об играх с угадыванием, но я не думаю, что это подходит, когда почти каждый популярный язык демонстрирует описанное поведение.
5
@Dunk: общий подход "догадкой" [arithmetics] [logic operator] [arithmetics]. Большинство программистов не создают беспорядок в скобках, как if(((x+getLowX()) < getMinX) || ((x-getHighX())>getMaxX())))большинство - большинство будет принимать арифметику над логикой и писать, if( ( x + getLowX() < getMinX ) || ( x - getHighX() > getMaxX() )) предполагая приоритет +выше <. Теперь интуитивно if( x ^ getMask() != PATTERN ) следует вести себя так же, XOR является арифметическим оператором. Факт, что это интерпретируется как if( x ^ ( getMask() != PATTERN ) )полностью нелогичное.
SF.

Ответы:

72

Языки скопировали это из C, а для C Деннис Ричи объясняет, что изначально, в B (и, возможно, в раннем C), была только одна форма, &которая в зависимости от контекста делалась побитовой и / или логической. Позже каждая функция получила свой оператор: &для побитовой и &&для логической. Затем он продолжает

Их запоздалое введение объясняет несостоятельность правил приоритета Си. В Б один пишет

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

проверить, aравно ли оно bи cне равно нулю; в таком условном выражении лучше &иметь более низкий приоритет, чем ==. При переходе от В к С, один хочет заменить &на &&в таком заявлении; чтобы сделать преобразование менее болезненным, мы решили оставить приоритет &оператора таким же относительно ==и просто &&немного отделить приоритет от &. Сегодня кажется, что было бы предпочтительнее переместить относительные приоритеты &и ==, и, таким образом, упростить общую идиому C: для проверки маскированного значения с другим значением необходимо написать

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

где внутренние скобки требуются, но легко забываются.

AProgrammer
источник
1
Разве это не потерпит неудачу, если c=2Или a==bприведет к ~0и нет 1?
SF.
Похоже, a == b возвращает 0 или 1, см. Cm.bell-labs.com/cm/cs/who/dmr/kbman.html .
AProgrammer
Проверьте ссылку в ответе и прочитайте предыдущий текст.
SShaheen
1
@MasonWheeler: Особенно во встроенных системах иногда необходимо использовать макросы, подобные функциям [в некоторых случаях они могут предложить на порядок более высокую производительность, чем встроенные функции, а в некоторых встроенных системах это может быть критично]. Объявление переменных в таких макросах невозможно; использование глобальной переменной внутри макроса может сработать, но выглядит довольно странно.
суперкат
6
@MasonWheeler: Можете ли вы найти Raspberry Pi или Arduino за $ 0,50 в количестве 1000?
суперкат
7

Битовые операторы связаны с логическими операторами как концептуально, так и по внешнему виду, что, вероятно, объясняет, почему они находятся рядом друг с другом в таблице приоритетов. Возможно, можно даже утверждать, что было бы непонятно, &чтобы быть выше ==, но &&быть ниже ==.

После того, как был установлен прецедент приоритета (!), Для других языков, вероятно, было бы лучше следовать ему для согласованности.

Однако я склонен согласиться с вами, что это не оптимально. В реальном использовании битовые операторы больше похожи на математические операторы, чем на логические, и было бы лучше, если бы они были сгруппированы с математическими операторами в приоритете.


источник