Целочисленное продвижение-каковы шаги
Этот код выводит B2
short a=-5;
unsigned short b=-5u;
if(a==b)
printf("A1");
else
printf("B2");
Я читал о целочисленном продвижении, но мне все еще неясно, как это работает в Примере здесь? Может ли кто-то тщательно опубликовать шаги, которые компилятор выполняет при расширении/усечении значений?
3 ответа:
Давайте пройдемся по вашему коду:
short a = -5;
A = -5, что укладывается в короткий отрезок. Пока все так просто.
unsigned short b = -5u;
- 5u означает применение унарного оператора
-
к константе 5u. 5u является (unsigned int) 5, а унарный оператор-
не продвигается, поэтому вы получаете 4294967291, что равно 2^32-5. (Update: я немного ошибся в своем первоначальном ответе; смотрите тестовый сценарий, который показывает, что эта версия правильна здесь http://codepad.org/hjooaQFW )Теперь, когда мы помещаем это в b, это усекается до беззнакового короткого (обычно 2 байта), поэтому b = 65531, что равно 2^16-5.
if( a == b )
В этой строке a и b повышаются до ints, так что сравнение может происходить правильно. Если бы они были повышены до шорт, б потенциально обернулся бы вокруг. Если бы они были повышены до неподписанных шорт, а потенциально обернулась бы вокруг.
Это все равно что сказать
if( (int) a == (int) b )
. И A = -5, поэтому (инт) а = -5 и B = 65531, так (инт) б = 65531, потому что целых чисел больше, чем шорты.
a == b
a
иb
оба повышаются доint
в приведенном выше выражении.unsigned short b=-5u;
В этом объявлении
-5U
преобразуется вunsigned short
посредством целочисленного преобразования (здесь применяется C99, 6.3.1.3p2) и становится большим значением.(C99, 6.3.1. 3p2) " в противном случае, если новый тип не имеет знака, значение преобразуется путем многократного добавления или вычитания на единицу больше максимального значения, которое может быть представлено в новом типе, пока значение не окажется в диапазоне нового типа. тип."
b
значение тогда(unsigned short) ((unsigned int) USHRT_MAX + 1 -5)
, которое является(unsigned short) 65531
, ЕслиUSHRT_MAX
является(unsigned short) 65535
.Итак, что у вас есть:
(short) -5 == (unsigned short) 65531
, что эквивалентно после целочисленного продвижения обоих операндов к:
-5 == 65531
, что эквивалентно
0
.
short
tounsigned short
- это преобразование (таким образом, имеющее ранг преобразования)
short
toint
- это продвижение (таким образом, имеющее ранг продвижения)Акции предпочтительнее конверсий из-за рейтинга. Повышение происходит во время арифметических и других операций. Преобразования происходят при простом хранении одного интегрального типа внутри другого. Арифметические операции могут вызывать конверсии, а также рекламные акции, чтобы принудить типы вместе. Другой пример:
unsigned int u = 2; int i = 2; u + i;
i
есть преобразовано (не повышено) вunsigned
.Ваше значение преобразуется в большее значение, потому что оно оборачивается вокруг из-за того, что
unsigned
. Затем они повышаются доint
. Таким образом,a != b
из-за этого.