¿Por qué debería uno deshabilitar las advertencias del compilador?

26

Esta respuesta y los comentarios agregados muestran una forma de deshabilitar varias advertencias del compilador mediante #pragmadirectivas.

¿Por qué querría uno hacer eso? Por lo general, las advertencias están ahí por una razón, y siempre he sentido que son buenas razones. ¿Hay algún "caso válido" en el que las advertencias se deshabiliten? En este momento no puedo pensar en ninguno, pero tal vez solo soy yo.

takrl
fuente
44
No estoy seguro de por qué alguien marcó esto para cerrar. Me parece una pregunta eminentemente razonable. +1
@Alastair Pitts: propuse una migración a los programadores. Me di cuenta de mi error más tarde.
Tugrul Ates
3
Los mensajes de advertencia están ahí por una razón, sí, pero también hay una razón por la que no son mensajes de error .
Solomon Slow
2
@jameslarge Tu comentario resume muy bien la situación. Una advertencia es el compilador diciéndole que una situación es plausiblemente incorrecta , lo que implica posiblemente correcto . Si definitivamente estuvo mal, entonces sería un error. Dado que algunas advertencias pueden ser falsos positivos, siempre debe haber una forma de escribir código de manera que elimine la advertencia. Desafortunadamente, a veces la forma más pragmática de hacerlo es a través de un pragma; de ahí el nombre.
Eric Lippert
No es incapacitante, se esconde. El problema seguirá ahí solo porque no lo verás tal como está
Sisir

Respuestas:

11

Solo he tenido una situación en la que desactivé una advertencia. Considero errores de advertencia, por lo que normalmente no publicaría con advertencias. Sin embargo, mientras desarrollaba una API en un cliente, me enfrenté al problema de que un método que una aplicación necesitaba en una fase de migración y que ningún otro debería usar debía ser incluido en la biblioteca.

La mejor manera que pude encontrar para decirles a todos los usuarios de la API que no deberían llamar a este método fue marcarlo como obsoleto. Sin embargo, eso significaba que el único caso de uso válido estaba marcado como una advertencia de compilación.

Eric Lippert ha escrito algunas publicaciones sobre advertencias donde encontrará información sobre cómo piensa el equipo compilador sobre las advertencias.

Campos internos de tipos internos

Las directivas no utilizadas no están marcadas con advertencias

Runa FS
fuente
10

Aquí hay algunas advertencias en las que la documentación da razones por las que es posible que desee deshabilitarlas:

Otros ejemplos incluyen advertencias sobre el uso de métodos depreciados si sabe que todavía desea usar el método anterior o tener miembros privados que nunca se leen localmente, sino con reflexión.

En mi experiencia, C # tiene menos necesidad de deshabilitar las advertencias que otros lenguajes como C ++. Esto se debe principalmente a que, como Eric Lippert dice en su blog , "intentan reservar advertencias solo para aquellas situaciones en las que podemos decir con casi certeza que el código está roto, es engañoso o inútil".

ICR
fuente
3
Agradable. Creo que el primero es más claro, porque proporciona un caso muy específico y una justificación (el tercero, por ejemplo, muestra una porción de código que nunca pasaría una revisión en mi equipo). Esta pregunta habla de advertencias obsoletas / depricadas. Básicamente, todavía son necesarios en el código heredado, pero desea desalentar cualquier código nuevo para que no los use. El código heredado debe tener las advertencias suprimidas.
Greg Jackson
He realizado una gran cantidad de programación de macros en Excel y tuve que deshabilitar las advertencias por varias razones, como el guardado automático, la salida automática, las notificaciones, etc. Por supuesto, es posible que no esté al tanto de estas advertencias ...
Dave Mess
@ICR No recuerdo deshabilitar las advertencias del compilador en Java en absoluto. Todo lo que hago es evitar el uso de métodos obsoletos.
Mahmoud Hossam
@Mahmoud Muy a menudo me encuentro teniendo que suprimir las advertencias "no controladas" cuando hago cualquier cosa remotamente compleja con genéricos. Pero probablemente sea injusto agrupar Java con C ++ en el frente ridículo de advertencias: edité mi respuesta.
ICR
@ICR Java impone el uso de genéricos para proporcionar seguridad de tipos en colecciones, mientras que algunos lo ven como una restricción, creo que es una característica, hace que escribir código sea un poco doloroso, pero salva vidas, y sí, la salida del compilador C ++ da un poco de miedo cuando se trata de STL o cualquier cosa con plantillas.
Mahmoud Hossam
8

Un ejemplo en C que encuentro variantes de regularmente:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

El argumento solo es relevante en algunas plataformas, pero en las que no es relevante, mi compilador se quejará, y dado que tengo advertencias convertidas en errores, evitará que se genere.

La conversión de advertencias en errores requiere una escotilla de escape para "no este, lo sé mejor que el compilador en este caso".

pjc50
fuente
6

Muchas bibliotecas Java indispensables nunca se han actualizado para eliminar la necesidad de tipos de letra inseguros. Es necesario suprimir esas advertencias para que otras advertencias más importantes se noten y corrijan.

Kevin Cline
fuente
5

Hago un trabajo incrustado y parece recordar una o dos veces cuando desactivé las advertencias porque estaba haciendo algo que parecía inútil para el compilador, pero que en realidad tenía efectos reales en el hardware.

El único otro momento es cuando estoy trabajando en bases de código con ideas dispares de alguna estructura de datos (como ¿cómo representar matrices de bytes - char o unsigned char?). En estos casos, podría deshabilitar las advertencias porque la alternativa es pasar días revisando el código y modificando una parte, o colocando cientos de yesos.

Michael Kohne
fuente
3

Hay bastantes razones para deshabilitar selectivamente las advertencias del compilador, incluso para proyectos que buscan las mejores prácticas.

  • Diferentes compiladores (o diferentes versiones de los mismos compiladores) : los
    compiladores manejan las advertencias de manera sutilmente diferente. Dar advertencias falsas positivas que no afectan a otros compiladores. En este caso, podría tener sentido deshabilitar la advertencia para esos compiladores, en lugar de editar un código válido para silenciar una advertencia de falsos positivos que solo afecta a ciertos compiladores, especialmente para compiladores más antiguos que eventualmente dejarán de ser compatibles.
  • Con código generado:
    algunas advertencias relacionadas con la higiene del código (código muerto, cuerpo duplicado de declaraciones condicionales, comparaciones que exceden los límites de tipo) pueden ignorarse de forma segura ya que son inofensivas y el compilador las optimizará.
    Por supuesto, generar código que no genere estas advertencias inofensivas también es una opción, pero puede ser más problemático de lo que vale.
  • Advertencias para el código externo:
    Quizás utilice una implementación de suma de comprobación qsort o md5 bien conocida que se incluye en su proyecto. Muchos proyectos utilizan el código y se sabe que funciona bien, aunque puede haber algunas advertencias exigentes que normalmente corrige para su propio código.
    Sin embargo, para el código externo, puede ser menos complicado simplemente deshabilitar la advertencia (suponiendo que definitivamente sea inofensivo).
  • Advertencias causadas por encabezados del sistema:
    aunque GCC / Clang, por ejemplo -isystem, admite , hay casos en que las diferencias en los encabezados del sistema provocan advertencias que pueden ignorarse (quizás una función tiene un valor de retorno firmado en un sistema pero no en otro), lo que provoca -Wsign-compareadvertencias.
    Otro caso puede ser las macros definidas en los encabezados del sistema, puede copiar y pegar las macros en su propio código para modificarlas, pero todas las cosas consideradas es mejor no tener que preocuparse por mantener macros de bibliotecas de terceros ... así que es mejor solo para silenciar la advertencia (quizás la macro pierde un elenco causando, -Wsign-conversionpor ejemplo).
  • Advertencias no utilizadas en el código auxiliar:
    puede advertir sobre parámetros no utilizados, sin embargo, al eliminar una biblioteca completa en un solo archivo que solo contiene funciones de código auxiliar, no es útil forzar (void)arg1; (void)arg2; (void)arg3; ...el cuerpo de cada función de código auxiliar.
    Mejor simplemente suprimir -Wunused-parameteren este caso.

Tenga en cuenta que en todos estos ejemplos, es asumido deshabilitar las advertencias no va a ocultar errores reales, por ejemplo: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, tal vez -Wpedantic... y que sabe lo que está haciendo!

ideasman42
fuente
2

Válido o no, a veces se hace para omitir la directiva "tratar las advertencias como errores" en el servidor de compilación.

Aparte de eso, tampoco puedo pensar en ninguno. Las advertencias de discapacidad suelen ser un signo de un "hax feo" ...

David Božjak
fuente
2

La última vez que deshabilitamos ciertas advertencias, fue porque un interno nos había dejado un código incorrecto. Lo tengo funcionando mucho mejor, con límites de conversión claros que reemplazan la representación de datos fortuita.

Mientras tanto, necesitábamos compilarlo y queríamos activar la opción "las advertencias son errores", por lo que suprimimos algunas de las advertencias.

David Thornley
fuente
2

Actualmente, la única advertencia que ignoro es

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Debido a que Microsoft no implementa la especificación C ++ (¡la documentación incluso dice que no lo hacen!) Y permite que las funciones declaren lanzamientos específicos y todas las funciones solo pueden lanzar throw () o throw (...), es decir, nada o todo.

Desde HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
Casey
fuente