Ответ 1
Когда вы меняете значение,
unsigned char x = ...;
int y = x << 16;
Тип x
продвигается до int
, если unsigned char
соответствует int
(большинство систем) или unsigned
, если unsigned char
не помещается в int
(редкий 1). Пока ваш int
будет шириной 25 бит или шире, тогда никакие данные не будут отброшены 2.
Обратите внимание, что это полностью не связано с тем, что 16
имеет тип int
.
/* All three are exactly equivalent */
x << 16;
x << 16u;
x << (unsigned char) 16;
Источник: от n1516 (черновик C99):
§6.5.7, пункт 3: Операторы побитового сдвига
Целочисленные рекламные акции выполняются для каждого из операндов. Тип результата то из продвинутого левого операнда.
§6.3.1.1 пункт 2: логические символы и целые числа
Если int может представлять все значения исходного типа (ограниченные шириной, для бит-поле), значение преобразуется в int; в противном случае он преобразуется в беззнаковое внутр. Они называются целыми рекламными акциями.
Сноска:
1: Некоторые чипы DSP, а также некоторые суперкомпьютеры Cray, как известно, имеют sizeof(char) == sizeof(int)
. Это упрощает проектирование блока загрузки нагрузки процессора за счет дополнительного потребления памяти.
2: Если ваш сдвиг влево продвинут на int
, а затем переполняет int
, это поведение undefined (демоны могут вылететь из вашего носа). Для сравнения, переполнение unsigned
всегда хорошо определено, поэтому сдвиги бит обычно должны выполняться на типах unsigned
.