c++ gcc warnings compiler-warnings gcc-warning

c++ - ¿Cómo activar(literalmente) TODAS las advertencias de GCC?



warnings compiler-warnings (7)

Y todavía no tengo idea si esta lista es completa.

Probablemente lo sea, pero la única lista que es 100% completa es la fuente real del compilador. Sin embargo, ¡GCC es grande ! Y no sé si todos los parámetros de línea de comandos se recopilan en un lugar o se distribuyen en varios archivos fuente. También tenga en cuenta que algunas advertencias son para el preprocesador, algunas para el compilador real y otras para el enlazador (que es un programa completamente separado, y que se encuentran en el paquete binutils) por lo que es muy probable que estén dispersas.

Me gustaría habilitar, literalmente, TODAS las advertencias que tiene GCC. (Pensarías que sería fácil ...)

  • Uno pensaría que -Wall podría hacer el truco, pero ¡no! Todavía necesito -Wextra .

  • Uno pensaría que "¡ -Wextra podría hacer el truco, pero no! No todas las advertencias enumeradas here (por ejemplo, -Wshadow ) están habilitadas por esto. Y todavía no tengo idea si esta lista es completa.

¿Cómo le digo a GCC que habilite (no if''s, and''s, o but''s) todas las advertencias que tiene?


Alguien ha creado un conjunto de herramientas para determinar el conjunto completo de advertencias para una versión determinada de GCC o Clang.

Para GCC, la copia de la lista completa de advertencias proporcionada por esta herramienta para su versión del compilador parece ser la única manera de asegurarse de que todas las advertencias estén activadas, ya que (a diferencia de Clang) GCC no proporciona -Weverything .

La herramienta parece analizar el archivo c.opt real en el código fuente de GCC, por lo que sus resultados deben ser definitivos.

El repositorio también contiene archivos de texto con las listas de advertencia generadas para la mayoría de las versiones de GCC y Clang (actualmente Clang 3.2 a 3.7 y GCC de 3.4 a 5.3).

github.com/barro/compiler-warnings


De esta página :

Tenga en cuenta que algunos indicadores de advertencia no están implícitos en -Wall . Algunos de ellos advierten acerca de construcciones que los usuarios generalmente no consideran cuestionables, pero que en ocasiones es posible que desee verificar; otros advierten sobre construcciones que son necesarias o difíciles de evitar en algunos casos, y no hay una forma simple de modificar el código para suprimir la advertencia. Algunos de ellos son habilitados por -Wextra pero muchos de ellos deben habilitarse individualmente.

¿Supongo que la pregunta es cuáles ? Quizás podría grep esa página para todas las líneas que comienzan con -W, y obtener una lista completa de banderas de advertencia. Luego, compare las listas con -Wall y -Wextra . También hay -Wpedantic , aunque obviamente quieres ser aún más pedante todavía =)


Es simplemente imposible de programar con todas las advertencias habilitadas (a menos que vaya a ignorarlas, pero entonces, ¿para qué molestarse?). Por ejemplo, supongamos que utiliza el siguiente conjunto de indicadores: -Wstrict-prototypes -Wtraditional .

Incluso con dos advertencias habilitadas, el siguiente programa se quejaría.

/tmp $ cat main.c int main(int argc, char **argv) { return 0; } /tmp $ gcc -Wstrict-prototypes -Wtraditional main.c main.c: In function ‘main’: main.c:1:5: warning: traditional C rejects ISO C style function definitions [-Wtraditional] int main(int argc, char **argv) { ^

Puedes pensar "bueno, voy a usar prototipos de estilo antiguo". No, esto no funcionará.

/tmp $ cat main.c int main(argc, argv) int argc; char **argv; { return 0; } /tmp $ gcc -Wstrict-prototypes -Wtraditional main.c main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes] int main(argc, argv) ^

Y no, no especificar ningún prototipo también es incorrecto, ya que el compilador también se quejará.

/tmp $ cat main.c int main() { return 0; } /tmp $ gcc -Wstrict-prototypes -Wtraditional main.c main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes] int main() { ^

Si define alguna función dentro de su programa, no puede usar todas las banderas, porque el compilador se quejará de cualquier definición de función imaginable.

Para C ++, esto es posible (el indicador -Wtraditional no existe), y se pueden compilar programas muy simples. Para habilitar todas las advertencias, use la siguiente lista de advertencias (probablemente algunas advertencias estén duplicadas, porque no me molesté en filtrar las advertencias activadas por -Wall ).

-Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo -Wextra -Wall -Waddress -Waggregate-return -Warray-bounds -Wno-attributes -Wno-builtin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Winline -Wno-int-to-pointer-cast -Wno-invalid-offsetof -Winvalid-pch -Wunsafe-loop-optimizations -Wlogical-op -Wlong-long -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wno-mudflap -Wno-multichar -Wnonnull -Wno-overflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-aliasing=1 -Wstrict-overflow=5 -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas -Wno-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings


Estoy de acuerdo con las respuestas anteriores de que probablemente no sea beneficioso habilitar literalmente todas las advertencias, sin embargo, GCC proporciona una manera razonablemente conveniente para lograr esto. El comando

gcc -Q --help=warning

proporciona una lista de todas las opciones de advertencia compatibles con información sobre si están activas. Esto, por cierto, se puede usar para averiguar qué opciones están (no) habilitadas, por ejemplo, -Wall y -Wextra

gcc -Wall -Wextra -Q --help=warning

Para habilitar todas las advertencias, puede usar algunas expresiones regulares para extraer los parámetros de la línea de comando

gcc -Q --help=warning | sed -e ''s/^/s*/(/-/S*/)/s*/[/w*/]//1 /gp;d'' | tr -d ''/n''

Para mi GCC actual esto da:

-Wabi -Wabi-tag -Waddress -Waggregate-return -Waggressive-loop-optimizations -Waliasing -Walign-commons -Wampersand -Warray-bounds -Warray-temporaries -Wassign-intercept -Wattributes -Wbad-function-cast -Wbool-compare -Wombin-macro-redefinido -Wc ++ - compat -Wc ++ 0x-compat -Wc ++ 14-compat -Wc-binding-type -Wc90-c99-compat -Wc99-c11-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wcharacter-Truncation -Wchkp -Wclobbered -Wcomment -Wcompare-reals -Wconditionally-supported -Wconversion -Wconversion-extra -Wconversion-null -Wcoverage-mismatch -Wcpp -Wctor-dtor-privacy -Wdate-time -Wdeclaration -after-statement -Wdelete-incomplete -Wdelete-non-virtual-dtor -Wdeprecated -Wdeprecated-declarations -Wdesignated-init -Wdisabled-optimization -Wdiscarded-array-qualifiers -Wdescarded-qualifiers -Wdiv-by-zero -Wdouble-promotion -Weffc ++ -Wempty-body -Wendif-labels -Wenum-compare -Wextra -Wfloat-equal -Wformat-contains-nul -Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-signedness - Wformat-y2k -Wformat-zero-length -Wfree-nonheap-object -Wfunction-elimination -Wignored-qualifiers -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wimplicit-interface -Wimplicit-procedure -Wincompatible-pointer-types - Winherited-variadic-ctor -Winit-self -Winline -Wint-conversion -Wint-to-puninter-cast -Wintrinsic-shadow -Wintrinsics-std -Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch -Wjump-pierde - init -Wline-Truncation -Wliteral-sufijo -Wlogical-no-parentheses -Wlogical-op -Wlong-long -Wmain -Wmaybe-uninitized -Wmemset-transposed-args -Wmissing-llaves -Wmissing-declarations -Wmissing-field-initializers - Wmissing-include-dirs -Wmissing-parameter-type -Wmissing-prototypes -Wmultichar -Wrowrowing -Wnested-externs -Wnoexcept -Wnon-template-friend -Wnon-virtual-dtor -Wnonnull -Wodr -Wold-style-cast -Wold- style-declaration -Wold-style-definition -Wopenmp-simd -Woverflow -Woverlength-strings -Woverloaded-virtual -Woverride-init -Wpacked -Wpacked-bitfield-compat -Wpadde d -Wrentrents -Wpedantic -Wpmf-converssions -Wpointer-arith -Wpointer-sign -Wpointer-to-int-cast -Wpragmas -Wproperty-assign-default -Wprotocol -Wreal-q-constant -Wrealloc-lhs -Wrealloc-lhs- all -Dredundant-decls -Wreorder -Wreturn-local-addr -Wreturn-type -Wselector -Wsequence-point -Wshadow -Wshadow-ivar -Wshift-count-negative -Wshift-count-overflow -Wsign-compare -Wsign-promo - Wsized-deallocation -Wsizeof-array-argument -Wsizeof-pointer-memaccess -Wstack-protector -Wstrict-null-sentinel -Wstrict-prototypes -Wstrict-selector-match -Wsuggest-attribute = const -Wsuggest-attribute = format -Wsuggest- attribute = noreturn -Wsuggest-attribute = pure -Wsuggest-final-methods -Wsuggest-final-types -Wsuggest-override -Wswitch -Wswitch -Wswitch-bool -Wswitch-default -Wswitch-enum -Wsync-nand -Wsynth -Wsystem- encabezados -Wtabs -Wtarget-lifetime -Wtraditional -Wtraditional-conversion -Wtrampolines -Wtrigraphs -Wtype-limits -Wundeclared-selector -Wundef -Wunderflow -Wuninitialized -Wunknown-pragmas -Wuns optimizaciones de afe-loop -Wunsuffixed-float-constants -Wunused -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-dummy-argument -Wunused-function -Wunused-label -Wunused-local-typedefs - Wunused-macros -Wunused-parameter -Wunused-result -Wunused-value -Wunused-variable -Wuse-without-only -Wuseless-cast -Wvarargs -Wvariadic-macros -Wvector-operation-performance -Wvirtual-move-assign -Wvla - Wvolatile-register-var -Wwrite-strings -Wzero-as-null-puntero-constante -Wzerotrip -frequire-return-statement

Esto ahora se puede usar para llamar a GCC, es decir,

gcc $(gcc -Q --help=warning | sed -e ''s/^/s*/(/-/S*/)/s*/[/w*/]//1 /gp;d'' | tr -d ''/n'')

Sin embargo, tenga en cuenta que esto da como resultado advertencias debido a que algunas opciones de advertencia solo están disponibles para ciertos idiomas (por ejemplo, C++ ). Esto se podría evitar usando algunas expresiones regulares para incluir solo las opciones permitidas para el idioma actual.


Gcc 4.3+ nows -Q --help = advertencias, incluso puede especificar --help = warnings, C para imprimir las advertencias relacionadas con C.

Acabo de escribir un módulo m4 para aprovechar esto (también es compatible con clang''s -Weverything), consulte wget_manywarnings.m4

Cómo usarlo es bastante simple, básicamente el módulo en el que enciende cada indicador de advertencia. Y eliminas las advertencias según sea necesario; algunas son realmente muy detalladas. Ejemplo: configure.ac

Si no usa autotools, encontrará el código para activar todas las advertencias desactivadas en el módulo m4, que básicamente es la llamada gcc transmitida a través de awk:

flags="-Wall -Wextra -Wformat=2 "$(gcc -Wall -Wextra -Wformat=2 -Q --help=warning,C|awk ''{ if (($2 == "[disabled]" || $2 == "") && $1!~/=/ && $1~/^-W/&& $1!="-Wall") print $1 }''


No puedes.

El manual para GCC 4.4.0 es solo exhaustivo para esa versión, pero enumera todas las advertencias posibles para 4.4.0. Sin embargo, no están todos en la página a la que se vincula, por ejemplo, algunas opciones específicas de idioma están en las páginas para opciones de C ++ u opciones de Obj-C. Para encontrarlos, es mejor que consultes el Resumen de opciones

Activar todo incluiría -Wdouble-promotion que solo es relevante en las CPU con una unidad de coma flotante de precisión simple de 32 bits que implementa float en el hardware, pero emula el double en software. Hacer cálculos como double usaría la emulación de software y sería más lento. Eso es relevante para algunas CPU integradas, pero completamente irrelevante para las CPU de escritorio modernas con soporte de hardware para coma flotante de 64 bits.

Otra advertencia que no suele ser útil es -Wtraditional , que advierte sobre un código perfectamente formado que tiene un significado diferente (o no funciona) en C tradicional, por ejemplo, "string " "concatenation" o definiciones de función de ISO C. ¿De verdad te importa la compatibilidad con los compiladores de 30 años? ¿De verdad quieres una advertencia para escribir int inc(int i) { return i+1; } int inc(int i) { return i+1; } ?

Creo que -Weffc++ es demasiado ruidoso para ser útil, se basa en la primera edición obsoleta de Effective C ++ y advierte sobre construcciones que son perfectamente válidas en C ++ (y para las cuales las pautas cambiaron en ediciones posteriores del libro). No quiero ser advertido de que no he inicializado un miembro std::string en mi constructor; tiene un constructor predeterminado que hace exactamente lo que yo quiero, ¿por qué debería escribir m_str() para llamarlo? Las advertencias -Weffc++ que serían útiles son demasiado difíciles para que el compilador las detecte con precisión (dando falsos negativos), y las que no son útiles, como inicializar a todos los miembros de manera explícita, solo producen demasiado ruido, dando falsos positivos.

Luc Danton proporcionó un gran ejemplo de advertencias inútiles de -Waggregate-return que casi con certeza nunca tiene sentido para el código C ++.

es decir, realmente no quieres todas las advertencias, solo piensas que sí.

Repase el manual, lea sobre ellos, decida qué es lo que desea habilitar, pruébelos. La lectura de su manual de compilación es una buena cosa TM de todos modos, tomar un atajo y permitir advertencias que no entiende no es una muy buena idea, especialmente si se trata de evitar tener que RTFM.

Cualquiera que simplemente encienda todo probablemente lo esté haciendo porque no tiene ni idea porque o un jefe con cabello puntiagudo dijo "sin advertencias".

Algunas advertencias son importantes y otras no. Tienes que discriminar o desordenar tu programa. Considere, por ejemplo, -Wdouble-promotion . Si está trabajando en un sistema integrado, es posible que desee esto; si estás trabajando en un sistema de escritorio, probablemente no. ¿Y quieres -Wtraditional ? Lo dudo.

Editar: Ver también -Wall-all para habilitar todas las advertencias que están cerradas como WONTFIX.

Edición 2: en respuesta a la queja de DevSolar sobre que los archivos MAKE necesitan usar diferentes advertencias dependiendo de la versión del compilador, si -Wall -Wextra no es adecuado, entonces no es difícil usar CFLAGS específicos del compilador y específicos de la versión:

compiler_name := $(notdir $(CC)) ifeq ($(compiler_name),gcc) compiler_version := $(basename $(shell $(CC) -dumpversion)) endif ifeq ($(compile_name),clang) compiler_version := $(shell $(CC) --version | awk ''NR==1{print $$3}'') endif # ... wflags.gcc.base := -Wall -Wextra wflags.gcc.4.7 := -Wzero-as-null-pointer-constant wflags.gcc.4.8 := $(wflags.gcc.4.7) wflags.clang.base := -Wall -Wextra wflags.clang.3.2 := -Weverything CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))