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
, чем в тесте условного оператора).
Ответы
Ответ 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
Ваше условие будет истинным, если результат отличен от нуля. В вашем примере результат обеих операций будет эквивалентен, а второй вариант может быть даже немного быстрее, потому что некоторые процессоры могут проверить нуль проще, чем другие произвольные числа, НО:
Очевидно, что вы не можете выполнить второй вариант, если значение, которое вы проверяете, состоит из более чем одного бита. В этом случае вы должны использовать первый вариант. Это очевидно также применимо, если вы одновременно проверяете несколько бит.