Смена и назначение смен дают разные результаты - PullRequest
2 голосов
/ 08 июля 2020

Моя цель здесь - удалить byte-count+1 бит слева от этого 8-битного целого числа (или, как вы часто его называете, unsigned char.

Должно быть действительно просто, но этот бит кода

uint8_t val = 0xC3;
uint8_t byte_count = 2;
uint8_t cc = val << (byte_count+1) >> (byte_count+1);
printf("%X", cc);

Дает мне C3 в результате.

А этот

uint8_t val = 0xC3;
uint8_t byte_count = 2;
uint8_t cc = val;
cc <<= (byte_count+1);
cc >>= (byte_count+1);
printf("%X", cc);

дает мне только 3.

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

Почему это происходит?

1 Ответ

2 голосов
/ 08 июля 2020

Продвижение.

Наткнувшись на несколько ключевых слов, я обнаружил продвижение и погуглил. Найдено этот ответ .

Меньшие типы данных будут неявно повышены до int / unsigned в выражении. Этот другой ответ объясняет это подробно.

Поскольку наш начальный операнд uint8_t повышается до целого числа с большим количеством битов, то его сдвиг на (в данном случае) 3 и обратно не приведет к дольше «удалить» эти биты. Это потому, что они больше не будут выходить за границу битов в первом сдвиге. это означает, что он представляет собой память, размер которой нельзя изменить). Он также возвращает lvalue, представляющий левый операнд, поэтому его тоже нельзя повышать.

printf("%d\n", sizeof(
    (uint8_t)2 + (uint8_t)3
));

//Output: 4
...