2009-02-05 15 views

Respuesta

24

Oh, sí. Pero al revés. Ignorando esa advertencia me causó un gran dolor de cabeza un día. Estaba escribiendo una función que trazó un gráfico y mezclé variables con signo y sin signo. En un lugar, comparé un número negativo con uno sin signo:

int32_t t; ... 
uint32_t ut; ... 

if(t < ut) { 
    ... 
} 

¿Adivina qué sucedió? El número firmado se promocionó al tipo sin firmar, y por lo tanto fue mayor al final, a pesar de que estaba por debajo de 0 originalmente. Me tomó un par de horas hasta que encontré el error.

+0

La solución está lejos de ser trivial. 'if (t <0 || unsigned (t) MSalters

+0

'if (t dalle

3

debe cambiar a y b para utilizar ambos tipos con signo, o ambos usan tipos sin firmar. Pero eso puede no ser práctico (por ejemplo, tal vez fuera de su control).

La advertencia está allí para detectar comparaciones entre un entero con signo con un valor negativo y un entero sin signo: si las magnitudes de ambos números son pequeñas, la primera se considerará (incorrectamente) más grande que la última.

2

los operadores binarios a menudo convierten ambos tipos en el mismo antes de hacer la comparación, ya que uno no está firmado, también convertirá el int en unsigned. Normalmente esto no causará demasiados problemas, pero si su int es un número negativo, esto causará errores en las comparaciones.

p. Ej. -1 es igual a 4294967295 cuando se convierte de firmado a sin firmar, ahora compare eso con 100 (sin firmar)

+0

En realidad, -1! = 2^32 en binario. Eso solo es cierto para los enteros de 32 bits. –

30

Nunca ignore las advertencias del compilador.

+0

El problema es que estoy encendiendo/Wall, que en el compilador de MS arroja muchas cosas que realmente no importan (creo que gcc es mejor en esto). –

+0

+2 si pudiera porque esto es realmente un buen consejo. –

+1

GCC's -WeffC++ es un conjunto bastante bueno para ignorar, en realidad. O Visual C++ quejándose de que un condicional en una función de plantilla es "siempre verdadero" o "siempre falso" como resultado de un parámetro de plantilla. – Tom

2

Las advertencias están ahí para un propósito ... ¡Te hacen pensar mucho sobre tu código!

Personalmente, siempre expulsaba explícitamente el signo -> sin firmar y sin firmar -> firmado si fuera posible. Al hacer esto, se asegura de que se haga cargo de la transacción y de que sepa qué va a suceder. Me doy cuenta de que no siempre será posible, dependiendo del proyecto, hacer esto, pero siempre apuntar a las advertencias del compilador ... ¡solo puede ayudar!

4

Si usted tiene que hacer la pregunta, usted no sabe lo suficiente acerca de si es seguro para desactivarlo, así que la respuesta es No.

no me desactivarlo - No asumo siempre saber mejor que el compilador (no menos importante porque a menudo no), y más particularmente porque a veces cometo errores por descuido cuando un compilador no lo hace.

+1

+1 por expresarlo tan sucintamente. Hay muchos escritores de compiladores y solo uno de mí. Su conocimiento colectivo (y base de clientes) es más grande. La advertencia está ahí por una razón. –

0

He estado escribiendo código por más tiempo del que me gustaría admitir.Por experiencia personal, ignorar las advertencias del compilador aparentemente pedante a veces puede arrojar resultados muy desagradables.

Si te molestan y aceptas la situación, configura un molde y sigue adelante.

Eventualmente estas cosas pasan de un matiz pasado por alto en una decisión consciente cuando se diseña un nuevo código. El resultado deja menos espacio para que las cajas de esquina de mickmouse arruinen su día o el de sus clientes y un software de mejor calidad en general.

+0

El lanzamiento explícito eliminará la advertencia, pero no importa de qué lado lo lances, estás agregando dragones a tu código. Si es necesario, envía ambos a un tipo firmado más grande (si hay uno) y luego compara. –

0

Incluso he configurado el compilador para hacer que esa advertencia sea un error de compilación. por las razones que todos los otros chicos ya mencionaron.

Si alguna vez encuentro una discrepancia entre firma/no firma, me pregunto por qué elegí una "firma" diferente. Por lo general, es un error de diseño.

0

@gimel La explicación acerca de disparar la pierna entera del encontrado detrás de su enlace es realmente buena para este problema.

- "Alguien que evita los problemas simples puede simplemente encaminarse hacia uno no tan simple".

Esto es siempre cierto cuando se realizan conversiones entre diferentes tipos y no se comprueban los valores que podrían perjudicarlo.

/Johan

Actualización: La forma correcta de convertir de uint a int es comprobar los valores contra limits.h, o algo por el estilo. (Pero rara vez lo hago yo mismo, incluso tú sé que debería ... :-)

0

Creo que es mejor convertir su número firmado en un número firmado (antes de la comparación). Más que al revés.

Cuestiones relacionadas