Banderas para permitir advertencias exhaustivas y detalladas de g ++

A menudo, en C bajo gcc , comenzaré con el siguiente conjunto de banderas de advertencia (dolorosamente ensambladas a partir de múltiples fonts):

 -Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \ -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \ -Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \ -Wfloat-equal -pedantic -ansi 

Construiré (al menos mis versiones de depuración) con este conjunto de advertencias y arreglaré todo lo que pueda (generalmente todo), y luego solo eliminaré indicadores si no son relevantes o no se pueden reparar (casi nunca es el caso). Algunas veces, también -Werror si tengo que alejarme mientras compilo.

Estoy recogiendo C ++ (sí, tengo 15 años de retraso), y me gustaría empezar con el pie derecho.

Mi pregunta es: ¿alguien tiene un conjunto similar precomstackdo de banderas de advertencia completas para C ++ bajo g++ ? (Sé que muchos de ellos serán lo mismo).

Revisé y encontré el conjunto mínimo de inclusiones que debería obtener el nivel máximo de advertencia. Luego eliminé de la lista el conjunto de advertencias que, en mi opinión, en realidad no indican que algo malo esté sucediendo, o bien, tengo demasiados falsos positivos para usar en una construcción real. Comenté por qué se excluyó a cada uno de los que excluí. Este es mi último conjunto de advertencias sugeridas:

-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused

Advertencias cuestionables que están presentes:

  • -Wno-unused porque a menudo tengo variables que sé que usaré más adelante, pero aún no tengo la funcionalidad escrita. Eliminar las advertencias sobre eso me permite escribir en mi estilo preferido de diferir ocasionalmente la implementación de las cosas. Es útil desactivarlo de vez en cuando para asegurarse de que nada se deslice entre las grietas.

  • -Wdisabled-optimization parece una configuración de preferencia de usuario fuerte. Acabo de agregar esta a mi comstackción (solo para comstackciones optimizadas por razones obvias) y no resultó nada, por lo que no parece ser una advertencia especialmente hablador, al menos por la forma en que el código. Lo incluyo (aunque el código que desencadena esta advertencia no es necesariamente incorrecto) porque creo en trabajar con mis herramientas en lugar de contra ellas. Si gcc me dice que no puede optimizar el código para la forma en que lo escribí, entonces debería revisarlo. Sospecho que el código que desencadena esta advertencia podría beneficiarse de ser más modular, independientemente, así que aunque el código no es técnicamente incorrecto (probablemente), estilísticamente es probable que lo sea.

  • -Wfloat-equal advierte sobre comparaciones seguras de igualdad (en particular, comparación con un valor no calculado de -1). Un ejemplo en mi código donde uso esto es que tengo un vector de flotación. Repaso este vector, y hay algunos elementos que aún no puedo evaluar cuáles deberían ser, así que los configuro en -1.0f (ya que mi problema solo usa números positivos, -1 está fuera del dominio). Luego reviso y actualizo -1.0f valores. No se presta fácilmente a un método de operación diferente. Sospecho que la mayoría de las personas no tienen este problema, y ​​la comparación de un número exacto en coma flotante es probablemente un error, así que lo incluyo en la lista predeterminada.

  • -Wold-style-cast tiene muchos falsos positivos en el código de la biblioteca que estoy usando. En particular, la familia de funciones htonl utilizada en la creación de redes, así como la implementación de encriptación de Rijndael (AES) que estoy usando, tiene modelos antiguos que me advierten. Tengo la intención de reemplazar ambos, pero no estoy seguro si hay algo más en mi código que pueda quejarse. Sin embargo, la mayoría de los usuarios deberían tener esto activado por defecto.

  • -Wsign-conversion fue difícil (y casi no llegó a la lista). Encenderlo en mi código generó una gran cantidad de advertencias (más de 100). Casi todos ellos eran inocentes. Sin embargo, he tenido cuidado de usar enteros con signo en los que no estaba seguro, aunque para mi dominio de problema en particular, generalmente obtengo un ligero aumento de eficiencia usando valores sin signo debido a la gran cantidad de división de enteros que hago. Sacrifiqué esta eficiencia porque me preocupaba la posibilidad de promocionar accidentalmente un entero con signo a un sin signo y luego dividirlo (lo cual no es seguro, a diferencia de la sum, la resta y la multiplicación). Al activar esta advertencia, pude cambiar de manera segura la mayoría de mis variables a tipos sin firmar y agregar algunos modelos en otros lugares. Actualmente es un poco difícil de usar porque la advertencia no es tan inteligente. Por ejemplo, si hace unsigned short + (integral constant expression) , ese resultado se promueve implícitamente a int. A continuación, advierte sobre un posible problema de signo si asigna ese valor al unsigned short unsigned o unsigned short , aunque sea seguro. Esta es definitivamente la advertencia más opcional para casi todos los usuarios.

  • -Wsign-promo : ver -Wsign-conversion .

  • -Wswitch-default parece inútil (no siempre quiere un caso predeterminado si ha enumerado todas las posibilidades de forma explícita). Sin embargo, activar esta advertencia puede hacer cumplir algo que probablemente sea una buena idea. Para los casos en los que explícitamente desea ignorar todo, excepto las posibilidades enumeradas (pero otros números son posibles), luego poner por default: break; para hacerlo explícito. Si enumera explícitamente todas las posibilidades, activar esta advertencia le ayudará a asegurarse de poner algo como assert (false) para asegurarse de que ha cubierto todas las opciones posibles. Le permite ser explícito en lo que es el dominio de su problema y lo aplica programáticamente. Sin embargo, tendrás que tener cuidado con solo pegar assert (false) en todas partes. Es mejor que no hacer nada con el caso predeterminado, pero como es habitual con assert, no funcionará en versiones de lanzamiento. En otras palabras, no puede confiar en que valide los números que obtiene de, por ejemplo, una conexión de red o una base de datos sobre la que no tiene control absoluto. Las excepciones o el regreso temprano son la mejor manera de manejar eso (¡pero aún así requiere que tenga un caso predeterminado!).

  • -Werror es importante para mí. Al comstackr grandes cantidades de código en una comstackción de varios subprocesos con múltiples destinos, es fácil que una advertencia se desvanezca. Convertir las advertencias en errores garantiza que las note.

Luego hay un conjunto de advertencias que no están incluidas en la lista anterior porque no las encontré útiles. Estas son las advertencias y mis comentarios sobre por qué no los incluyo en la lista predeterminada:

Advertencias que están ausentes:

  • -Wabi no es necesario porque no estoy combinando binarios de comstackdores diferentes. Traté de comstackr con él de todos modos, y no se activó, por lo que no parece innecesariamente detallado.

  • -Waggregate-return no es algo que considero un error. Por ejemplo, se activa cuando se usa un bucle for basado en rango en un vector de clases. La optimización del valor de retorno debería encargarse de cualquier efecto negativo de esto.

  • -Wconversion en este código: short n = 0; n += 2; short n = 0; n += 2; La conversión implícita a int causa una advertencia cuando luego se convierte de nuevo a su tipo de destino.

  • -Weffc++ incluye una advertencia si todos los miembros de datos no se inicializan en la lista de inicializadores. Intencionalmente no hago esto en muchos casos, por lo que el conjunto de advertencias es demasiado abarrotado para ser útil. Sin embargo, es útil activarlo de vez en cuando y buscar otras advertencias (como destructores no virtuales de clases base). Esto sería más útil como una colección de advertencias (como -Wall ) en lugar de una sola advertencia en sí misma.

  • -Winline está ausente porque no utilizo la palabra clave en línea con fines de optimización, solo para definir funciones en línea en los encabezados. No me importa si el optimizador realmente lo enmarca. Esta advertencia también se queja si no puede alinear una función declarada en un cuerpo de clase (como un destructor virtual vacío).

  • -Winvalid-pch encuentra porque no uso encabezados precomstackdos.

  • -Wmissing-format-attribute no se usa porque no uso extensiones gnu. Lo mismo para -Wsuggest-attribute y varios otros

  • Potencialmente notable por su ausencia es -Wno-long-long , que no necesito. -std=c++0x con -std=c++0x ( -std=c++11 en GCC 4.7), que incluye tipos enteros long long . Los que están atrapados en C ++ 98 / C ++ 03 pueden considerar agregar esa exclusión de la lista de advertencia.

  • -Wnormalized=nfc ya es la opción predeterminada, y parece ser la mejor.

  • -Wpadded se enciende ocasionalmente para optimizar el diseño de las clases, pero no se deja activado porque no todas las clases tienen elementos suficientes para eliminar el relleno al final. En teoría, podría obtener algunas variables adicionales para ‘gratis’, pero no vale la pena el esfuerzo extra de mantener eso (si el tamaño de mi clase cambia, no es fácil eliminar esas variables previamente libres).

  • -Wstack-protector no se usa porque no uso -fstack-protector

  • -Wstrict-aliasing=3 está activado por -Wall y es el más preciso, pero parece que el nivel 1 y 2 dan más advertencias. En teoría, un nivel inferior es una advertencia “más fuerte”, pero es a costa de más falsos positivos. Mi propio código de prueba comstackdo limpiamente en los 3 niveles.

  • -Wswitch-enum no es el comportamiento que quiero. No quiero manejar cada statement de cambio explícitamente. Sería útil si el lenguaje tuviese algún mecanismo para activar esto en instrucciones de cambio especificadas (para asegurar que los cambios futuros en la enumeración se manejen en todas partes que necesitan), pero es excesivo para una configuración de “todo o nada”.

  • -Wunsafe-loop-optimizations provocan demasiadas advertencias falsas. Puede ser útil aplicar esto periódicamente y verificar manualmente los resultados. Como ejemplo, generó esta advertencia en mi código cuando hice un bucle sobre todos los elementos en un vector para aplicarles un conjunto de funciones (usando el bucle for para el rango). También es una advertencia para el constructor de una matriz de const std :: string (donde este no es un bucle en el código de usuario).

  • -Wzero-as-null-pointer-constant y -Wuseless-cast son advertencias GCC-4.7-only, que -Wuseless-cast cuando haga la transición a GCC 4.7.

He archivado algunos informes de fallos / solicitudes de mejoras en gcc como resultado de algunas de estas investigaciones, así que con suerte podré agregar eventualmente más advertencias de la lista “no incluir” a la lista “incluir” . Esta lista incluye todas las advertencias mencionadas en este hilo (además, creo que algunas más). Muchas de las advertencias no mencionadas explícitamente en este artículo se incluyen como parte de otra advertencia que menciono. Si alguien nota por completo advertencias que están excluidas de esta publicación, házmelo saber.

editar: Parece que me había perdido varios (que ahora he agregado). En realidad, hay una segunda página en http://gcc.gnu.org que está bastante bien escondida. Opciones generales de advertencia y opciones de C ++ (baje hasta la parte inferior para ver las advertencias)

D’oh, todas mis búsquedas originales arrojaron el 99% de las publicaciones sobre cómo suprimir las advertencias (lo cual es bastante raro), pero acabo de encontrar este comentario , que tiene este encantador conjunto de indicadores (algunos menos relevantes):

Cruz marcada con:

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

 -g -O -Wall -Weffc++ -pedantic \ -pedantic-errors -Wextra -Waggregate-return -Wcast-align \ -Wcast-qual -Wconversion \ -Wdisabled-optimization \ -Werror -Wfloat-equal -Wformat=2 \ -Wformat-nonliteral -Wformat-security \ -Wformat-y2k \ -Wimplicit -Wimport -Winit-self -Winline \ -Winvalid-pch \ -Wlong-long \ -Wmissing-field-initializers -Wmissing-format-attribute \ -Wmissing-include-dirs -Wmissing-noreturn \ -Wpacked -Wpadded -Wpointer-arith \ -Wredundant-decls \ -Wshadow -Wstack-protector \ -Wstrict-aliasing=2 -Wswitch-default \ -Wswitch-enum \ -Wunreachable-code -Wunused \ -Wunused-parameter \ -Wvariadic-macros \ -Wwrite-strings 

Entonces, creo que es un buen punto de partida. No me di cuenta de que era una estafa, pero al menos estaba profundamente enterrado. 🙂

Algunos de ellos ya están incluidos en -Wall o -Wextra .

Una buena configuración de base para C es:

-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror

y para C ++

-ansi -pedantic -Wall -Wextra -Weffc++

(omitiendo -Werror para C ++ ya que -Weffc++ tiene algunas molestias)

Tratar

 export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' | sort | uniq` -pedantic -fdiagnostic-show-option -Werror" 

Es un comienzo rápido y sucio que definitivamente necesitará un poco de ajuste; Por un lado, incluso si llama al comstackdor por el nombre apropiado para su idioma (por ejemplo, g ++ para C ++), recibirá advertencias que no se aplican a ese idioma (y el comstackdor levantará las manos y se negará a continuar hasta que elimine la advertencia).

Otra cosa es que agregué -Werror, porque si no estás arreglando las advertencias, ¿por qué te preocupas de activarlas? También puede sacar advertencias de la lista (Por ejemplo, casi nunca uso -Waggregate-return con C ++).

Algunas advertencias no harán nada sin otras opciones relacionadas con el rendimiento ( -Wstack-protector ). -fdiagnostic-show-option y el manual de GCC son tus amigos.

Por cierto, algunas advertencias son mutuamente excluyentes; en particular, utilizando -Wtraditional y -Wold-style-definition junto con -Werror , no se comstackrá.