Таким образом, место, где битовые поля выгодны, это то, где у вас есть много флагов bool, которые вы можете упаковать в одно слово. Код для тестирования одного конкретного флага сопоставим, но код для тестирования конкретного подшаблона флагов может быть намного короче, хотя вам может потребоваться написать тест самостоятельно:
// using bool
bool a,b,c,d;
if (a && !b && c && !d) ...
// hoping the compiler knows what we are doing
enum { A= 0x01, B= 0x02, C= 0x04, D= 0x08};
if ((flags&A) && !(flags&B) && (flags&C) && !(flags&D)) ...
// Optimise it ourselves:
enum { A= 0x01, B= 0x02, C= 0x04, D= 0x08};
if ((flags & (A|B|C|D)) == (A|!B|C|!D)) ...
В первом случае Компилятор должен загрузить каждое из мест, хотя это может произойти раньше. В последних случаях, как минимум, он может загрузить значение один раз и выполнить несколько операций в ядре. Хороший оптимизатор может оптимизировать второй шаблон до третьего, то есть двух инструкций, хотя оптимизатор может также понять, что он может загружать все логические операции как «длинные» для уменьшения пропускной способности, и они, по крайней мере, все будут находиться в одной строке кэша. , что почти так же хорошо, как в наши дни.
Но в любом случае 3-я форма выиграет против первой формы для краткости, а также сэкономит немного места.
Обратите внимание, что ваши два примера не проверяют одно и то же.
A & 5
проверяет, что 4-битный и 1-битный оба установлены, но полностью игнорирует 2-битный и любые старшие биты.
A == 5
проверяет, установлены ли 1-битный и 4-битный, но также проверяет, что ВСЕ ДРУГИЕ биты сброшены.