tag pattern number formato formatnumber fmt fecha c compiler-construction long-integer iso c89

pattern - Advertencia: esta constante decimal no está firmada solo en ISO C90



jstl fmt (3)

Las reglas para los tipos de constantes enteras decimales cambiaron entre las ediciones de 1990 y 1999 del estándar ISO C.

En la versión de 1990, el tipo de constante entero entero decimal sin sufijo es el primero de int , long int o unsigned long int en el que se puede representar su valor. (C90 no tenía tipo long long o unsigned long long ).

En las versiones de 1999 y 2011, su tipo es uno de int , long int , long long int ; Nunca es de ningún tipo sin firmar.

El tipo de una constante particular (como 2147483648 ) variará dependiendo de los rangos de los tipos de enteros para el compilador que está usando. Si el tipo long su compilador es de 32 bits, entonces 2147483648 será del tipo unsigned long si su compilador usa reglas C90, o del tipo long long si usa reglas C11 (se garantiza que el long long es de al menos 64 bits). El compilador te advierte sobre esto.

Puede agregar sufijos para especificar el tipo de una constante, pero no hay ningún sufijo para int . Puede agregar U para unsigned int , L para long , UL para largo sin firmar, etc.

Es importante tener en cuenta que -2147483648 no es una constante entera; más bien 2147483648 por sí mismo es una constante entera, y -2147483648 es una expresión que aplica un operador menos unario a esa constante. Bajo las reglas C90, si la constante es de tipo unsigned long , eso es un menos unario sin firma , que bajo las reglas de la aritmética sin signo produce el valor 2147483648 . Bajo las reglas de C99 o C11, es probable que 2147483648 sea ​​del tipo (con firma) long long , y -2147483648 produce -2147483648 , también del tipo long long .

A veces verá un código que usa (-2147483647 - 1) para evitar este problema; dado un int 32 bits, 2147483647 es de tipo int y el resultado de la expresión produce el valor int esperado sin desbordamiento.

Por supuesto, si su compilador tiene diferentes tamaños para los tipos de enteros, esto puede ser aún más complicado.

Pieza de código:

long rangeVar = 0; rangeVar = atol(p_value); if (rangeVar >= -2147483648 && rangeVar <= 2147483647)

Al compilar me sale:

Advertencia: esta constante decimal no está firmada solo en ISO C90

Gracias por adelantado


Sí, 2147483648 no es un valor positivo válido porque está fuera del rango para el complemento de 2 en máquinas de 32 bits, por lo que solo están tratando de advertirle que en algunos compiladores esto puede no darle el valor que desea si no se manejan La negación de una manera moderna.

Creo que vale la pena agregar otra respuesta para señalar que si observas la mayoría de las implementaciones de limits.h, verás que se (-2147483647 - 1) usando (-2147483647 - 1) .


Sí, eso es algo que el compilador no maneja muy bien. El problema es que durante la compilación, este es el número 2147483648 que se niega, y 2147483648 está fuera de rango para un entero. ¡Incluso si -2147483648 no lo fuera!

De todos modos, para deshacerte de la advertencia, puedes convertir la constante en un número de 64 bits escribiendo -2147483648LL .
Sin embargo, eso es excesivo, por lo que la forma preferida sería usar INT_MIN para la constante. Pero entonces necesitarás incluir <limits.h> .