Можете ли вы объяснить это - "правила, включающие смешанные типы операндов, не применяются к операторам сдвига"

Я не могу понять строку "Результат сдвига имеет тот же тип, что и сдвинутая вещь (после интегральных повышений)" в следующем отрывке из книги С Майка Банахана (раздел 2.8.2.3).

Важно отметить, что правила, включающие смешанные типы операндов, не применяются к операторам сдвига. Результат сдвига имеет тот же тип, что и сдвинутая вещь (после интегральных повышений), и больше ни от чего не зависит.

Если что-то уже преобразуется в целое число (как требуется при использовании оператора сдвига), то как его можно преобразовать обратно в тот же тип, которым оно изначально было, если, конечно, оно не находится справа от присвоения и присваивается переменная того же типа, что и до целочисленного продвижения? Кроме того, что именно означает строка "правила, включающие смешанные типы операндов, не применяются к операторам сдвига"?

Пожалуйста, пролите свет на обе части вопроса. Спасибо.

Ниже приведены скриншоты из книги, касающиеся продвижения по службе при использовании побитовых операторов и при смешанных выражениях в целом, соответственно.

введите описание изображения здесь

введите описание изображения здесь

1 ответ

Решение

Это довольно просто; тип результата операции сдвига - это тип операнда LHS. Для большинства бинарных операторов результат основан на операндах LHS и RHS, но операторы сдвига отличаются.

unsigned char      uc = 0x08;
unsigned short     us = 0x0008;
unsigned int       ui = 0x00000008;
unsigned long long ul = 0x0000000000000008;

(Я предполагаю, что sizeof(unsigned int) == 4 за этот ответ. Детали должны измениться, если они отличаются, но концепции остаются неизменными.)

Теперь рассмотрим некоторые выражения:

uc + uc;

Оба типа конвертируются в int и результат int,

us + us;

Опять же, оба типа преобразуются в int и результат int,

us + ui;
ui + us;

Значение в us преобразуется в unsigned int и результат unsigned int (обратите внимание, что предыдущие значения были преобразованы в signed int ака int).

ui + ul;
ul + ui;

Оба эти выражения преобразовывают ui для unsigned long long и результат unsigned long long, Обратите внимание, что эти выражения симметричны; тип результата (и, действительно, с + оператор, значение результата) не зависит от того, какое значение находится на LHS, а какое от RHS оператора.

Так много для обычных операций; теперь как насчет смен?

uc << uc;

LHS преобразуется в int обычными арифметическими преобразованиями и результатом является int,

us << us;

Этот результат также является int,

ui << ui;

Этот результат является unsigned int,

ul << ul;

Этот результат является unsigned long long, Но как насчет смешивания типов?

uc << ul;   // Result: int
ul << uc;   // Result: unsigned long long
us << ui;   // Result: int
ui << us;   // Result: unsigned int
ui << ul;   // Result: unsigned int
ul << ui;   // Result: unsigned long long

Продвинутый тип операнда LHS управляет типом результата. Для типов короче intрезультат int; для других типов тип - это тип операнда LHS.

Это все, что означает ваша цитата.

Другие вопросы по тегам