Подтвердить что ты не робот

If (mask & VALUE) или if ((mask & VALUE) = VALUE)?

Вероятно, вы знакомы с битовой маской enum, например:

enum Flags {
    FLAG1 = 0x1,
    FLAG2 = 0x2,
    FLAG3 = 0x4,
    FLAG4 = 0x8,

    NO_FLAGS = 0,
    ALL_FLAGS = FLAG1 | FLAG2 | FLAG3 | FLAG4
};

f(FLAG2 | FLAG4);

Я видел много кода, который затем тестирует определенный бит в маске, например

if ((mask & FLAG3) == FLAG3)

Но разве это не эквивалентно этому?

if (mask & FLAG3)

Есть ли какая-то причина для использования первой версии? На мой взгляд, вторая более короткая версия более разборчива.

Возможно, оставшиеся привычки от программистов C, которые считают, что истинные значения должны быть преобразованы в 1? (Хотя даже там более длинная версия имеет больше смысла в задании или в выражении return, чем в тесте условного оператора).

4b9b3361

Ответ 1

Конструкция if ((mask & FLAG3) == FLAG3) проверяет, имеются ли в маске все биты в FLAG3; if (mask & FLAG3) проверяет, есть ли любой.

Если вы знаете, что FLAG3 имеет ровно 1 бит, они эквивалентны, но если вы потенциально определяете составные условия, может быть яснее получить привычку явно тестировать все биты, если это то, что вы имеете в виду.

Ответ 2

Если это для битового набора, поэтому вам нужно сравнить только бит одиночный, это нормально, если if(mask & value).

Но предположим, что у вас есть IP-адрес, хранящийся на ant int32, и вы хотите знать, есть ли он 192.168.*, тогда вам нужно будет сделать:

if((ip & 0xFFFF0000) == 0xC0A80000) // assuming some endianness representation.

Ответ 3

Даже для однобитового значения, где эти операторы фактически эквивалентны, я всегда предпочитаю явное сравнение.

  • Это делает цель более ясной. Мы действительно заинтересованы в сравнении флагов. (x & Flag) == Flag является установленным шаблоном, и я могу обрабатывать и распознавать его в мгновение ока.

  • Я обычно предпочитаю явно неявные преобразования. Я делаю исключение для состояний сбоев (например, я пишу if (file) вместо if (file.good())), но при работе с числами 0 не является "отказоустойчивым", его число равно числу других. Мне не нравится относиться к нему по-разному в логическом контексте.

Ответ 4

if принимает значение boolean (bool). Первое выражение относится к типу bool, тогда как последнее представляет собой числовое значение, которое будет неявно преобразовано в bool.

Ответ 5

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

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