Pregunta

Tengo una función pequeña muestra:

#define VALUE 0

int test(unsigned char x) {
  if (x>=VALUE)
    return 0;
  else
    return 1;
}

Mi compilador me advierte que la comparación (x> = VALOR) es cierto en todos los casos, lo cual es correcto, porque x es un personaje sin signo y valor se define con el valor 0. Así que cambié mi código para:

if ( ((signed int) x ) >= ((signed int) VALUE ))

Sin embargo, la advertencia se produce de nuevo. Lo he comprobado con tres versiones del CCG (todas las versiones> 4,0, a veces hay que permitir que -Wextra).

En el caso cambiada, tengo esta conversión explícita y debe ser una comparación int firmado. ¿Por qué se afirma que la comparación es siempre verdad?

¿Fue útil?

Solución

A pesar de la fundición, la comparación es cierto en todos los casos de comportamiento definido. El compilador todavía determina que (signed int)0 tiene el valor 0, y todavía determina que (signed int)x) es no negativo si el programa ha definido comportamiento (casting de unsigned a firmado no está definido si el valor está fuera del intervalo para el tipo firmado).

Así que el compilador sigue advertencia, ya que continúa eliminando el caso más en conjunto.

Editar : Para silenciar la advertencia, escribir el código como

#define VALUE 0

int test(unsigned char x) {
#if VALUE==0
  return 1;
#else
  return x>=VALUE;
#endif
}

Otros consejos

x es un unsigned char, lo que significa que está entre 0 y 256. Puesto que un int es más grande que un char, fundición unsigned char a signed int todavía conserva las chars valor original. Dado que este valor es siempre> = 0, su if siempre es cierto.

Todos los valores de un abeto unsigned char pueden perfectamente en su int, por lo que incluso con el elenco nunca se tiene un valor negativo. El elenco que necesita es signed char - sin embargo, en ese caso, debería declarar como x signed en la firma de la función. No hay ningún punto situado a los clientes que usted necesita un valor sin signo, cuando en realidad lo que necesita un ser firmado.

El #define de VALUE a 0 significa que su función se reduce a esto:

int test(unsigned char x) {
  if (x>=0)
    return 0;
  else
    return 1;
}

Desde x siempre se pasa como un unsigned char, entonces siempre tendrá un valor entre 0 y 255 incluido, independientemente de si lanzas x o 0 a un signed int en la declaración if. El compilador, por tanto, le advierte de que x será siempre mayor o igual que 0, y que la cláusula else nunca puede ser alcanzado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top