Подумайте обо всех изменениях типов и происходящих конверсиях.Их как минимум 4.
0xff
, int
преобразуется в uint32_t
, затем происходит &
.Здесь нет проблем.
len & 0xff;
Затем этот результат присваивается char
, со знаком char
в случае OP.Это присваивает 0x81
(129), выходящий за пределы диапазона char
-> Определенное реализацией поведение .Общий результат просто передает наименьшие биты.
char pop1 = len & 0xff;
, почему символ обрабатывается как 32-битное значение (?)
Он еще не обрабатывается как32-разрядное значение без знака , но в виде 8-разрядного значения со знаком .
Затем код передается char pop1
(возможно со значением -127) вprintf();
и включает продвижение аргумента по умолчанию в качестве аргумента функции ....printf()
получает int
со значением -127.
printf(...,pop1);
printf("%02x \n",pop1);
ожидает unsigned
, а не int
.Поскольку значение -127 не может быть представлено как int
и unsigned
, (c11 §6.5.2.2 6), спецификатор преобразования недопустим с этим аргументом, и в результате получается неопределенное поведение (УБ).(§7.21.6.1 9).Обычно происходит то, что битовая комбинация -127
, переданная как int
, интерпретируется как битовая комбинация для unsigned
и приводит к "ffffff81"
.
printf("%02x \n",pop1);
Во избежаниеРеализация определенного поведения и UB, рекомендую ниже.Для эффективного кода без знака четко используйте типы без знака , объекты и константы.
unsigned char pop1 = len & 0xffu;
// or
uint8_t pop1 = len & 0xffu;