Вопрос по c++, c – что это означает, что поразрядный сдвиг влево без знака с 16

13

я читаю .cpp файл, содержащийunsigned char переменная, она пытается сдвинуть влево по битам 16 бит, так какunsigned char состоит из 8 бит, сдвиг влево на 16 бит сотрет все биты и заполнит его восемью нулями.

unsigned char byte=0xff; byte << 16;

Как написано, компилятор оптимизирует операцию сдвига, поскольку ничего не делает. Какой был настоящий код? Jonathan Leffler
Значение выражения не назначено. user180326
Все встроенные операторы работают с объектами размером не менее int (см.stackoverflow.com/a/5563131/14065). Таким образом:sizeof(byte << 16) == sizeof(int) Martin York
Вы можете посмотреть на это:stackoverflow.com/questions/437470/… Anders

Ваш Ответ

2   ответа
16

Когда вы меняете значение,

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;

Source: от n1516 (черновик C99):

& # xA7; 6.5.7 пункт 3: Операции побитового сдвига

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.

& # xA7; 6.3.1.1 параграф 2: логические, символы и целые числа

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.

Footnotes:

1: Известно, что некоторые DSP-чипы, а также некоторые суперкомпьютеры Cray имеютsizeof(char) == sizeof(int), Это упрощает конструкцию устройства хранения нагрузки процессора за счет дополнительного потребления памяти.

2: Если ваш левый сдвиг повышен доint а затем переполняетintЭто неопределенное поведение (демоны могут вылететь из носа). Для сравнения, переполнениеunsigned всегда четко определен, поэтому сдвиги немногоshould обычно делается наunsigned типы.

Error: User Rate Limit ExceededintError: User Rate Limit Exceededunsigned charError: User Rate Limit ExceededintError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded leomayleomay
Error: User Rate Limit Exceededunsigned charError: User Rate Limit Exceededint leomayleomay
Error: User Rate Limit Exceededx = x << 16Error: User Rate Limit Exceededx = 0.
1

Еслиchar подходит внутриint, он будет повышен доint и результат будет таким, как вы ожидаете. Если это не так, это неопределенное поведение в соответствии со стандартом, и, вероятно, выдаст предупреждение компиляции. Из стандарта:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

Error: User Rate Limit Exceededunsigned charError: User Rate Limit ExceededintError: User Rate Limit Exceededunsigned intError: User Rate Limit Exceededint.
Error: User Rate Limit Exceeded0 << 16Error: User Rate Limit ExceededintError: User Rate Limit Exceeded
Error: User Rate Limit ExceededcharError: User Rate Limit ExceededintError: User Rate Limit Exceededunsigned intError: User Rate Limit Exceededunsigned intError: User Rate Limit Exceeded1 << 16Error: User Rate Limit ExceededintError: User Rate Limit Exceeded

Похожие вопросы