2011-07-18 18 views
5

Sé que esta es una pregunta simple pero estoy confundido. Tengo una advertencia bastante típico gcc que es generalmente fácil de solucionar:
warning: comparison between signed and unsigned integer expressionsconstante hexadecimal en c no está firmada aunque utilicé el sufijo L

Cada vez que tengo una constante hexadecimal con el bit más significativo, como 0x80000000L, el compilador lo interpreta como signo. Por ejemplo compilar este código con -Wextra hará que el aviso (4.4x gcc, 4.5x):

int main() 
{ 
long test = 1; 
long *p = &test; 
if(*p != 0x80000000L) printf("test"); 
} 

He sufijada específicamente la constante todo el tiempo, así que por qué sucede esto?

+3

posible duplicado de [Constante hexadecimal sin signo en C?] (Http://stackoverflow.com/questions/4737798/unsigned-hexadecimal-constant-in-c) – Nemo

+0

FWIW, gcc 4.6.1 en Linux, con '- Wall -ansi -pedantic' emitió solo una advertencia, sobre el control que llega al final de la función no-vacía. ¿Posiblemente otra característica que no llegó a la cima de la prioridad de los escritores del compilador hasta hace muy poco? – vpit3833

Respuesta

9

La respuesta a esta pregunta es relevante:

Unsigned hexadecimal constant in C?

una constante con L sufijo hexagonal tendrá el primero de los siguientes tipos que pueden mantener su valor:

long 
unsigned long 
long long 
unsigned long long 

Véase el C99 draft, sección [6.4.4.1], para más detalles.

En su plataforma, long es probablemente 32 bits, por lo que no es lo suficientemente grande como para mantener la constante (positiva) 0x80000000. Por lo tanto, su constante tiene el tipo unsigned long, que es el siguiente tipo en la lista y es suficiente para mantener el valor.

En una plataforma donde long tenía 64 bits, su constante tendría el tipo long.

1

Según el estándar c, las constantes hexadecimales no están firmadas.

+6

No es cierto en general ... Las constantes hexadecimales se firmarán si la variante firmada es suficiente para mantener el valor. Ver http://stackoverflow.com/questions/4737798/unsigned-hexadecimal-constant-in-c. (En particular, si "largo" fuera de 64 bits, esta constante estaría firmada, no sin signo.) – Nemo

0

Es un unsigned long entonces. Supongo que el compilador decide que es muy probable que un hexadecimal como ese sea anónimo. Pruebe a enviarlo (unsigned long)0x80000000L

0

Las constantes hexadecimales en C/C++ siempre están sin firmar. Pero puede usar typecast explícito para suprimir la advertencia.

+1

Las constantes hexadecimales en C/C++ no _ _ son siempre unsigned. Siempre son positivos, lo cual no es lo mismo en absoluto. – Nemo

+0

@Nemo Tienes razón sobre las constantes hexadecimales. Encontré otro comportamiento extraño. Modifiqué la comparación de cambio de ejemplo a continuación: 'if ((long long) * p!= LLONG_MAX) printf ("prueba"); 'y el compilador me da' 'advertencia: la comparación es siempre cierta debido al rango limitado de tipo de datos'' – qoyllur

+0

@Nemo Hola nemo, si quieres enviar una respuesta detallada que explique la diferencia con algunos ejemplos y lo marcaré como correcto. De lo contrario, presentaré lo que escribió y ampliaré la sustancia y la marcaré correctamente, ya que parece ser la respuesta correcta de lo que puedo decir. Al contrario de lo que pensé, parece que las constantes hexadecimales no tienen un sufijo. [mscs link] (http://msdn.microsoft.com/en-us/library/2k2xf226.aspx) – test

1

Debido a que su compilador utiliza 32 bits long s (y, presumiblemente, de 32 bits int s así) y 0x80000000 ajuste costumbre en un entero de 32 bits, por lo que el compilador lo interpreta como signo. Cómo solucionar esto depende de lo que estás tratando de hacer.

Cuestiones relacionadas