Чому бітові оператори мають нижчий пріоритет, ніж порівняння?


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 - це, природно, допомогти відповідачам краще зрозуміти поставлене запитання та дати кращі відповіді. Розумієте, це не місце для The Guessing Game - або, як говорить сторінка туру , "Це не дискусійний форум. Немає чіт-чату".
гнат

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 ) )абсолютно протиінтуїтивний.
СФ.

Відповіді:


72

Мови скопіювали це з C, а для C Денніс Річі пояснює, що спочатку в B (а можливо, і на початку C) існувала лише одна форма, &яка залежно від контексту робила побіжно та або логічно. Пізніше кожна функція отримала свого оператора: &для бітової та &&для логічної. Потім він продовжує

Їх затяжне введення пояснює невірність правил пріоритету С. В Б один пише

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

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

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

там, де внутрішні дужки потрібні, але легко забуваються.


1
Хіба це не вдалося б, якщо б c=2це a==bпризвело ~0і ні 1?
СФ.

Здається, a == b повертає 0 або 1, див. Cm.bell-labs.com/cm/cs/who/dmr/kbman.html .
AProgrammer

Перевірте посилання у відповіді та прочитайте попередній текст.
SShaheen

1
@MasonWheeler: Особливо у вбудованих системах іноді доводиться використовувати макроси, подібні до функцій [у деяких випадках вони можуть запропонувати на замовлення кращої продуктивності, ніж вбудовані функції, а також у деяких вбудованих системах, які можуть бути критичними]. Змінна декларація в межах таких макросів неможлива; використання глобальної змінної в макросі може спрацювати, але здається справді прискіпливою.
supercat

6
@MasonWheeler: Чи можете ви знайти Raspberry Pi або Arduino за $ 0,50 у кількості 1000?
supercat

7

Побітові оператори пов'язані з логічними операторами як концептуально, так і за зовнішнім виглядом, що, ймовірно, пояснює, чому вони знаходяться поруч один з одним у таблиці пріоритету. Можливо, можна навіть стверджувати, що заплутатися в тому, &щоб бути вищим ==, але &&тоді бути нижчим ==.

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

Однак я схильний погоджуватися з вами, що це не оптимально. Насправді використання бітових операторів більше схоже на математичні оператори, ніж на логічні, і було б краще, якби вони були згруповані з математичними операторами в пріоритеті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.