побитовые флаги устанавливаются произвольно

Я изучал C ++ (и программирование в этом отношении) только неделю, поэтому в этом вопросе может не хватать понимания фундаментальных принципов программирования, но здесь ничего не говорится:

unsigned int bitFlags()
{
unsigned char option1 = 0x01; // hex for 0000 0001
unsigned char option2 = 0x02; // hex for 0000 0010
unsigned char option3 = 0x04; // hex for 0000 0100
unsigned char option4 = 0x08; // hex for 0000 1000
unsigned char option5 = 0x10; // hex for 0001 0000
unsigned char option6 = 0x20; // hex for 0010 0000
unsigned char option7 = 0x40; // hex for 0100 0000
unsigned char option8 = 0x80; // hex for 1000 0000

unsigned char myflags; // byte-size value to hold some combination of the above 8 options

myflags |= option1|option2|option3;

if (myflags&option8)
return 1;
else
return 0;
}

int main()
{
std::cout << bitFlags() << "\n";
return 0;
}

Итак, я установил только 3 флага (опция1, опция2, опция3). Теперь запрос флага работает как положено (возвращает 1 для опций 1/2/3 и 0 для остальных) вплоть до опции 7/8. Несмотря на то, что option7 / 8 не установлены, функция возвращает 1. Что приводит меня к выводу, что unsigned char myflags выглядит следующим образом в двоичном виде: 1100 0000. Ну, тогда,

1) Что здесь происходит? Почему 2 бита уже используются? Как неподписанный символ использует 2 бита в первую очередь? Разве самый старший бит не должен быть зарезервирован только для знаковых переменных?

2) Почему мы используем оператор побитового присваивания | = для установки битовых флагов, когда он дает неожиданные результаты. Если мы просто назначим myflags = option3 | option2 | option3 работает как положено — запрос для option7 / 8 возвращает 0.

(Существует высокая вероятность того, что я понятия не имею, о чем говорю!)

-1

Решение

Вы не инициализировали myflags равным 0, поэтому перед вами или во флагах есть неизвестный мусор.

4

Другие решения

В C и C ++, если вы определяете переменную1 примитивного типа2 без явной инициализации он начинается в неопределенном состоянии, что объясняет поведение, которое вы видите здесь: вы «добавляете» (|=) флаги для переменной в неопределенном состоянии, таким образом, вы получаете другие вещи в дополнение к тому, что вы на самом деле указали.

«Мусор» в вашем случае происходит от того, что уже было в стеке ранее: он может исходить из предыдущего вызова функции (до main среда выполнения C ++ запускает свою долю кода инициализации), или весь стек может начинаться с предварительно заполненными значениями нежелательной почты, чтобы помочь вам обнаружить проблемы, подобные этой (это типично для отладочных сборок).

Если мы просто назначим myflags = option1 | вариант2 | option3 работает как положено

Вот почему ты здесь назначение option1 | option2 | option3перезаписывая что было в myflags На первом месте.

Как неподписанный символ использует 2 бита в первую очередь? Разве «старший» бит не должен быть зарезервирован только для знаковых переменных?

Старший бит используется в знаковых переменных для хранения знака3, в неподписанных типах у вас есть все биты, доступные для ваших целей.


  1. Исключение: глобалы и static местные жители инициализируются нулями автоматически.
  2. На самом деле, любой тип без предоставленного пользователем конструктора
  3. Это на самом деле поведение, зависящее от реализации.
0