Понимание 2^31 и -2^31 целочисленного продвижения

#include <stdio.h>

int main() {
    printf("sizeof(int): %zu\n", sizeof(int));
    printf("%d\n", 2147483648u > -2147483648);
    printf("%d\n", ((unsigned int)2147483648u) > ((int)-2147483648));
    printf("%d\n", 2147483648u != -2147483648);
    printf("%d\n", ((unsigned int)2147483648u) != ((int)-2147483648));
    return 0;
}

Вывод этого кода на C и C++, на cygwin64 и на машине rhel6.4 с gcc 5.2.0:

sizeof(int): 4
1
0
1
0

Согласно " Целым акциям", 2147483648u будет иметь тип unsigned int (даже без u суффикс) и -2147483648 типа int (по-прежнему). Почему разные результаты с явным приведением?

Согласно " Обычным арифметическим преобразованиям", этот параграф применяется:

В противном случае подпись отличается: если операнд с беззнаковым типом имеет ранг преобразования, больший или равный рангу типа подписанного операнда, то операнд с подписанным типом неявно преобразуется в тип без знака

Это означает, что правильный результат выглядит так:

2147483648u > 2147483648u
2147483648u != 2147483648u

были выполнены, потому что в 32 битах со знаком -2^31 и без знака 2 ^ 31 имеют одинаковое представление. Другими словами, результат с приведением верен. Что здесь происходит?

У меня такое ощущение, что каким-то образом целочисленное продвижение более высокого ранга применяется без разыгрыша, поэтому я получаю, например, 64-разрядное подписанное продвижение с обеих сторон - но почему?

Оба исполняемых файла скомпилированы как 64-битные, это может сыграть свою роль?

1 ответ

Решение

Там нет отрицательных целочисленных констант. Есть только положительные с одинарным - оператор применяется.

поскольку 2147483648 > INT_MAX, что способствует 2147483648 к следующему большему подписанному (потому что вы не добавили u) целочисленный тип, перед - применены.


Кстати, вот почему INT_MIN обычно определяется как (-INT_MAX - 1) в <limits.h>,;-)

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