Целочисленное продвижение-каковы шаги
Этот код выводит 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.
shorttounsigned short- это преобразование (таким образом, имеющее ранг преобразования)
shorttoint- это продвижение (таким образом, имеющее ранг продвижения)Акции предпочтительнее конверсий из-за рейтинга. Повышение происходит во время арифметических и других операций. Преобразования происходят при простом хранении одного интегрального типа внутри другого. Арифметические операции могут вызывать конверсии, а также рекламные акции, чтобы принудить типы вместе. Другой пример:
unsigned int u = 2; int i = 2; u + i;
iесть преобразовано (не повышено) вunsigned.Ваше значение преобразуется в большее значение, потому что оно оборачивается вокруг из-за того, что
unsigned. Затем они повышаются доint. Таким образом,a != bиз-за этого.