Часть кода:
long rangeVar = 0;
rangeVar = atol(p_value);
if (rangeVar >= -2147483648 && rangeVar <= 2147483647)
При компиляции я получаю:
предупреждение: эта десятичная константа не имеет знака только в ISO C90
Спасибо в Advance
Часть кода:
long rangeVar = 0;
rangeVar = atol(p_value);
if (rangeVar >= -2147483648 && rangeVar <= 2147483647)
При компиляции я получаю:
предупреждение: эта десятичная константа не имеет знака только в ISO C90
Спасибо в Advance
Правила для типов десятичных целочисленных констант изменялись между версиями стандарта 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
без переполнения.
Конечно, если ваш компилятор имеет разные размеры для целых типов, это может стать еще более сложным.
Да, это одна вещь, которая не очень хорошо обрабатывается компилятором. Проблема в том, что во время компиляции это число 2147483648, которое отрицается, и 2147483648 выходит за пределы диапазона для целого числа. Даже если -2147483648 не будет!
В любом случае, чтобы избавиться от предупреждения, вы можете превратить константу в 64-разрядное число, написав -2147483648LL
.
Однако это перебор, поэтому предпочтительным способом было бы использовать INT_MIN
для константы. Но тогда вам нужно включить <limits.h>
.
Да, 2147483648 не является допустимым положительным значением, потому что он выходит за пределы диапазона для 2-х доп-устройств на 32-битных машинах, поэтому они просто пытаются предупредить вас, что некоторые компиляторы могут не дать вам нужного вам значения, если они "Относитесь к отрицанию современным способом.
Я чувствую, что стоит добавить еще один ответ, чтобы указать, что если вы посмотрите на большинство возможностей limits.h, вы увидите, что они обойдутся этим, используя (-2147483647 - 1)
.