C 2018 6.5.4 5 сообщает нам, что оператор приведения в x > (signed short) y
выполняет преобразование:
Если перед выражением указать имя типа в скобках, значение выражения преобразуется в неквалифицированную версию именованного типа. Эта конструкция называется cast …
6.3.1.3 сообщает нам о конверсиях. Результат зависит от того, может ли значение в y
, 0xFFFF
(то есть 65535) быть представлено в signed short
. Стандарт C требует signed short
для представления до 32767, но это может быть и больше. Если это так, то параграф 1 говорит нам, что результат имеет то же значение. В противном случае пункт 3 гласит:
В противном случае новый тип подписывается и значение не может быть представлено в нем; либо результат определяется реализацией, либо определяется сигнал реализации.
Таким образом, если signed short
равно 16 битам, то (signed short) y
имеет значение, определенное реализацией, или сигнал повышается.
Во многих реализациях C результат будет -1. Это значение signed short
автоматически повышается до int
(из-за обычных целочисленных повышений в 6.3.1.1 1), а x > (signed short) y
фактически равно x > -1
. В этот момент спецификация оператора >
в 6.5.8 3 говорит нам (со ссылкой на обычные арифметические преобразования в 6.3.1.8) int
преобразуется в unsigned int
для соответствия x
. Преобразование выполняется в соответствии с 6.3.1.3 2:
В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного сложения или вычитания значения, превышающего максимальное значение, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне нового типа.
Это приводит к преобразованию -1 в UINT_MAX-1
, и выражение фактически равно 0xDEADBEEF > UINT_MAX-1
, что неверно, поскольку UINT_MAX
равно по крайней мере 0xFFFFFFFF
.
Правильно ли я предположить, что у, который был беззнаковым коротким, сначала явно приведен к подписанному короткому. Битовое представление остается прежним.
Нет, битовое представление не обязательно должно оставаться прежним.
Кроме того, может ли базовое представление битов изменяться при явном приведении?
Да. Приведения в C во многом определяются тем, как они влияют на значение . Они не определены как реинтерпретация битов исходного значения или, как правило, для сохранения битов исходного значения.
Как расширить маленькие типы по сравнению с большими?
Существует три варианта преобразования более узкого целого числа в более широкое целое:
- Если оба типа подписаны или оба без знака, результатом будет одно и то же значение.
- Если тип без знака преобразуется в более широкий тип со знаком, результатом будет то же значение.
- Если тип со знаком преобразуется в тип без знака, результат будет таким же, если он не отрицательный. Если оно отрицательное, применяется правило из пункта 6.3.1.3, приведенное выше.
Когда результат имеет то же значение:
- Для натуральных чисел результирующее значение представляется дополнительными нулевыми битами.
- Для отрицательных целых чисел результирующее значение представляется дополнительными однобитными, если используется дополнение двух. Тем не менее, стандарт C допускает представления дополнения и знака и величины, поэтому эзотерические или древние реализации C, использующие их, будут производить любые битовые комбинации, необходимые для представления требуемого значения.