Целочисленное продвижение-каковы шаги


Этот код выводит B2

short a=-5;
unsigned short b=-5u;
if(a==b)
    printf("A1");
else
    printf("B2");

Я читал о целочисленном продвижении, но мне все еще неясно, как это работает в Примере здесь? Может ли кто-то тщательно опубликовать шаги, которые компилятор выполняет при расширении/усечении значений?

3 8

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 to unsigned short - это преобразование (таким образом, имеющее ранг преобразования)

short to int - это продвижение (таким образом, имеющее ранг продвижения)

Акции предпочтительнее конверсий из-за рейтинга. Повышение происходит во время арифметических и других операций. Преобразования происходят при простом хранении одного интегрального типа внутри другого. Арифметические операции могут вызывать конверсии, а также рекламные акции, чтобы принудить типы вместе. Другой пример:

unsigned int u = 2; 
int i = 2; 
u + i;

i есть преобразовано (не повышено) в unsigned.

Ваше значение преобразуется в большее значение, потому что оно оборачивается вокруг из-за того, что unsigned. Затем они повышаются до int. Таким образом, a != b из-за этого.