Правила для типов десятичных целочисленных констант изменились между выпусками стандарта ISO С. 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
для длинных без знака и т. Д.
Важно помнить, что -2147483648
является , а не целочисленной константой; скорее 2147483648
само по себе является целочисленной константой, а -2147483648
является выражением, которое применяет унарный оператор минус к этой константе. Согласно правилам C90, если константа имеет тип unsigned long
, это беззнаковый унарный минус, который по правилам арифметики без знака дает значение 2147483648
. В соответствии с правилами C99 или C11 2147483648
, скорее всего, относится к типу (со знаком) long long
, а его отрицание приводит к -2147483648
, также типа long long
.
Иногда вы увидите код, который использует (-2147483647 - 1)
, чтобы избежать этой проблемы; для 32-битного int
, 2147483647
имеет тип int
, а результат выражения возвращает ожидаемое значение int
без переполнения.
Конечно, если ваш компилятор имеет разные размеры для целочисленных типов, это может стать еще более сложным.