Предупреждение: эта десятичная константа неподписанна только в ISO C90

Часть кода:

long rangeVar = 0;
rangeVar = atol(p_value);

if (rangeVar >= -2147483648 && rangeVar <= 2147483647)

При компиляции я получаю:

предупреждение: эта десятичная константа не имеет знака только в ISO C90

Спасибо в Advance

Ответ 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 без переполнения.

Конечно, если ваш компилятор имеет разные размеры для целых типов, это может стать еще более сложным.

Ответ 2

Да, это одна вещь, которая не очень хорошо обрабатывается компилятором. Проблема в том, что во время компиляции это число 2147483648, которое отрицается, и 2147483648 выходит за пределы диапазона для целого числа. Даже если -2147483648 не будет!

В любом случае, чтобы избавиться от предупреждения, вы можете превратить константу в 64-разрядное число, написав -2147483648LL.
Однако это перебор, поэтому предпочтительным способом было бы использовать INT_MIN для константы. Но тогда вам нужно включить <limits.h>.

Ответ 3

Да, 2147483648 не является допустимым положительным значением, потому что он выходит за пределы диапазона для 2-х доп-устройств на 32-битных машинах, поэтому они просто пытаются предупредить вас, что некоторые компиляторы могут не дать вам нужного вам значения, если они "Относитесь к отрицанию современным способом.

Я чувствую, что стоит добавить еще один ответ, чтобы указать, что если вы посмотрите на большинство возможностей limits.h, вы увидите, что они обойдутся этим, используя (-2147483647 - 1).