A menudo, en C debajo gcc
, comenzaré con el siguiente conjunto de indicadores de advertencia (ensamblados dolorosamente de múltiples fuentes):
-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é las banderas si no son relevantes o no se pueden arreglar (casi nunca es el caso). A veces, también agregaré -Werror
si tengo que alejarme mientras compilo.
Solo estoy recogiendo C ++ (sí, tengo 15 años de retraso), y me gustaría comenzar con el pie derecho.
Mi pregunta es: ¿Alguien tiene un conjunto similar precompilado de indicadores de advertencia completos para C ++ en g++
? (Sé que muchos de ellos serán iguales).
-Wall
) es un-Wbloody_everything
indicador :-)-Weverything
. He leído que incluso los desarrolladores de Clang ++ están un poco preocupados por los usuarios que lo activan; aparentemente estaba destinado solo para uso de desarrollo interno. Sin embargo, esto no tiene sentido, porque encender-Weverything
es probablemente la mejor manera posible de descubrir advertencias potencialmente útiles que no conocía antes.Respuestas:
Revisé y encontré el conjunto mínimo de inclusiones que deberían obtener el nivel máximo de advertencia. Luego eliminé de esa lista el conjunto de advertencias que siento que en realidad no indican que algo malo está sucediendo, o que tienen demasiados falsos positivos para ser utilizados en una compilación real. Comenté por qué cada uno de los que excluí fueron excluidos. Este es mi conjunto final 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:
Incluyo
-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 apagarlo de vez en cuando para asegurarse de que nada se escape por las grietas.-Wdisabled-optimization
parece una fuerte configuración de preferencia de usuario. Acabo de agregar este a mi compilación (solo para compilaciones optimizadas por razones obvias) y no apareció nada, por lo que no parece ser una advertencia especialmente comunicativa, al menos por la forma en que codifico. Lo incluyo (aunque el código que activa esta advertencia no es necesariamente incorrecto) porque creo en trabajar con mis herramientas en lugar de en contra de ellas. Si gcc me dice que no puede optimizar el código para la forma en que lo escribí, entonces debería considerar reescribirlo. Sospecho que el código que desencadena esta advertencia podría beneficiarse de ser más modular, sin embargo, aunque el código no es técnicamente incorrecto (probablemente), estilísticamente sí lo es.-Wfloat-equal
advierte sobre comparaciones de igualdad seguras (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. Paso por este vector, y hay algunos elementos que aún no puedo evaluar cuáles deberían ser, así que los configuré en -1.0f (dado que mi problema solo usa números positivos, -1 está fuera del dominio). Más tarde reviso y actualizo los valores de -1.0f. No se presta fácilmente a un método diferente de operación. 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, por lo 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 htonl de funciones utilizadas en redes, así como una implementación de encriptación Rijndael (AES) que estoy usando tiene modelos antiguos de los que me advierte. Tengo la intención de reemplazar ambos, pero no estoy seguro de si hay algo más en mi código que se queje. Sin embargo, la mayoría de los usuarios probablemente deberían tener esto activado de manera predeterminada.-Wsign-conversion
fue difícil (y casi no figura en la lista). Activarlo 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 donde no estaba seguro, aunque para mi dominio del problema particular, generalmente obtendría un ligero aumento de la eficiencia usando valores sin signo debido a la gran cantidad de división de enteros que hago. Sacrifiqué esta eficiencia porque estaba preocupado por promover accidentalmente un entero con signo a un sin signo y luego dividirlo (lo que no es seguro, a diferencia de la suma, la resta y la multiplicación). Activar esta advertencia me permitió cambiar de manera segura la mayoría de mis variables a tipos sin signo y agregar algunos lanzamientos en otros lugares. Actualmente es un poco difícil de usar porque la advertencia no es tan inteligente. Por ejemplo, si lo hacesunsigned short + (integral constant expression)
, ese resultado se promueve implícitamente a int. Luego advierte sobre un posible problema de signos si asigna ese valorunsigned
aounsigned 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 explícitamente). Sin embargo, activar esta advertencia puede hacer cumplir algo que probablemente sea una buena idea. Para los casos en los que desea ignorar explícitamente todo, excepto las posibilidades enumeradas (pero son posibles otros números), luego ingresedefault: break;
para hacerlo explícito. Si enumera explícitamente todas las posibilidades, activar esta advertencia lo ayudará a asegurarse de poner algo como afirmar (falso) para asegurarse de que haya cubierto todas las opciones posibles. Le permite ser explícito en cuál es el dominio de su problema y cumplirlo mediante programación. Sin embargo, tendrá que tener cuidado al pegar la afirmación (falso) en todas partes. Es mejor que no hacer nada con el caso predeterminado, pero como es habitual con afirmar, no funcionará en las versiones de lanzamiento. En otras palabras, no puede confiar en él para validar 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 regresar temprano son la mejor manera de manejar eso (¡pero aún así requieren que tenga un caso predeterminado!).-Werror
Es importante para mí. Al compilar grandes cantidades de código en una compilación de subprocesos múltiples con múltiples objetivos, es fácil que pase una advertencia. Convertir las advertencias en errores garantiza que los 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 ausentes:
-Wabi
no es necesario porque no estoy combinando binarios de diferentes compiladores. Intenté compilarlo 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 dispara cuando se usa un bucle for basado en rango en un vector de clases. La optimización del valor de retorno debe tener en cuenta los efectos negativos de esto.-Wconversion
se activa en este código:short n = 0; n += 2;
la conversión implícita a int provoca 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 está demasiado abarrotado para ser útil. Sin embargo, es útil encender 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 por sí sola.-Winline
está ausente porque no uso la palabra clave en línea para fines de optimización, solo para definir funciones en línea en los encabezados. No me importa si el optimizador realmente lo alinea. Esta advertencia también se queja si no puede en línea una función declarada en un cuerpo de clase (como un destructor virtual vacío).-Winvalid-pch
falta porque no uso encabezados precompilados.-Wmissing-format-attribute
no se usa porque no uso extensiones gnu. Lo mismo para-Wsuggest-attribute
y muchos otrosPotencialmente notable por su ausencia es
-Wno-long-long
, que no necesito. Compilo con-std=c++0x
(-std=c++11
en GCC 4.7), que incluyelong long
tipos enteros. Aquellos atascados 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 activa 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 adicional 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 a costa de más falsos positivos. Mi propio código de prueba compilado limpiamente en los 3 niveles.-Wswitch-enum
No es el comportamiento que quiero. No quiero manejar cada declaración de cambio explícitamente. Sería útil si el lenguaje tuviera algún mecanismo para activar esto en las instrucciones de cambio especificadas (para garantizar que los cambios futuros a la enumeración se manejen en todos los lugares donde deben estar), pero es excesivo para una configuración de "todo o nada".-Wunsafe-loop-optimizations
causa demasiadas advertencias espurias. Puede ser útil aplicar esto periódicamente y verificar manualmente los resultados. Como ejemplo, generó esta advertencia en mi código cuando recorrí todos los elementos en un vector para aplicarles un conjunto de funciones (usando el bucle for basado en rango). También es una advertencia para el constructor de una matriz const de const std :: string (donde esto no es un bucle en el código de usuario).-Wzero-as-null-pointer-constant
y-Wuseless-cast
son advertencias solo de GCC-4.7, que agregaré cuando haga la transición a GCC 4.7.He presentado algunos informes de errores / solicitudes de mejora en gcc como resultado de algunas de estas investigaciones, por lo que espero poder agregar 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 esta publicación se incluyen como parte de otra advertencia que sí menciono. Si alguien nota advertencias que están excluidas de esta publicación por completo, avíseme.
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 oculta. Opciones de advertencia generales y opciones de C ++ (desplácese hacia abajo para ver las advertencias)
fuente
-Wswitch-enum
advierte si no maneja explícitamente cada valor de enumeración en un conmutador ydefault
no cuenta como explícito. Por otro lado,-Wswitch-default
le advierte si su conmutador no tiene undefault
caso, incluso si ha cubierto explícitamente todos los valores posibles.-isystem
lugar de-I
su "código de biblioteca anterior" para evitar todos esos falsos positivosOh, todas mis búsquedas originales arrojaron el 99% de las publicaciones sobre cómo suprimir las advertencias (lo suficientemente aterrador), pero acabo de encontrar este comentario , que tiene este encantador conjunto de banderas (algunas menos relevantes):
Verificación cruzada con:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Entonces, creo que es un buen punto de partida. No me di cuenta de que se trataba de un engañado, pero al menos estaba profundamente enterrado. :-)
fuente
-Wall
no haga lo que uno esperaría. Pero gracias, ¡algunos de esos se ven muy útiles!-Waggregate-return
? Esto me da una advertencia por cada uso debegin/end()
Algunos de ellos ya están incluidos en
-Wall
o-Wextra
.Una buena configuración base para C es:
-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror
y para C ++
-ansi -pedantic -Wall -Wextra -Weffc++
(omitiendo
-Werror
C ++ ya que-Weffc++
tiene algunas molestias)fuente
-std=c89
. En modo C ++, es equivalente a-std=c++98
. es decir, si está especificando alguna otrastd
, no useansi
Tratar
Ese es un comienzo rápido y sucio que definitivamente necesitará algo de ajuste; por un lado, incluso si llama al compilador por el nombre apropiado para su idioma (por ejemplo,
g++
para C ++), recibirá advertencias que no se aplican a ese idioma (y el compilador levantará las manos y se negará a continuar hasta que eliminar la advertencia).Otra cosa es que agregué
-Werror
, porque si no está arreglando las advertencias, ¿por qué le importa encenderlas? También puede eliminar las advertencias de la lista. (Por ejemplo, casi nunca lo uso-Waggregate-return
con C ++).Algunas advertencias no harán nada sin otras opciones relacionadas con el rendimiento (
-Wstack-protector
).-fdiagnostics-show-option
y el manual de GCC son tus amigos.Por cierto, algunas advertencias son mutuamente excluyentes; en particular usando
-Wtraditional
y-Wold-style-definition
junto con-Werror
, no se compilará.fuente
En mi Clion's CmakeLists.txt
fuente