Ответ 1
Правила для типов десятичных целочисленных констант изменялись между версиями стандарта ISO C 1990 и 1999 годов.
В версии 1990 года непостоянный десятичный целочисленный постоянный тип является первым из int
, long int
или unsigned long int
, в котором может быть представлено его значение. (C90 не имеет типа long long
или unsigned long long
).
В версиях 1999 и 2011 годов его тип является одним из int
, long int
, long long int
; он никогда не имеет никакого неподписанного типа.
Тип конкретной константы (например, 2147483648
) будет меняться в зависимости от диапазонов целых типов для используемого вами компилятора. Если ваш тип компилятора long
составляет 32 бита, тогда 2147483648
будет иметь тип unsigned long
, если ваш компилятор использует правила C90 или тип long long
, если он использует правила C11 (long long
гарантированно будет не менее 64 бит). Компилятор предупреждает вас об этом.
Вы можете добавить суффиксы, чтобы указать тип константы, но нет суффикса для простой подписки int
. Вы можете добавить U
для unsigned int
, L
для long
, UL
для unsigned long и т.д.
Важно помнить, что -2147483648
не является целочисленной константой; скорее 2147483648
сам по себе является целочисленной константой, а -2147483648
является выражением, которое применяет унарный оператор минус к этой константе. В соответствии с правилами C90, если константа имеет тип unsigned long
, то неподписанный унарный минус, который по правилам беззнаковой арифметики дает значение 2147483648
. В соответствии с правилами C99 или C11 2147483648
скорее всего будет иметь тип (подписанный) long long
, а отрицание его дает -2147483648
, также типа long long
.
Иногда вы можете увидеть код, который использует (-2147483647 - 1)
, чтобы избежать этой проблемы; 32-битный int
, 2147483647
имеет тип int
, и результат выражения дает ожидаемое значение int
без переполнения.
Конечно, если ваш компилятор имеет разные размеры для целых типов, это может стать еще более сложным.