Más allá de la configuración -Wall
y la configuración -std=XXX
, ¿qué otros indicadores de compilación realmente útiles, pero menos conocidos, existen para usar en C?
Estoy particularmente interesado en cualquier advertencia adicional, y / o convertir las advertencias en errores en algunos casos para minimizar absolutamente cualquier desajuste de tipo accidental.
c
gcc
compiler-flags
Matt Joiner
fuente
fuente
-save-temps
,-Wshadow
y-fmudflap
fueron los mejores hallazgos que no conocía, gracias a todos.gcc -c [flags-go-here] -o myprog.o myprog.c
para compilar (no vincular) un programa en C.Respuestas:
Varias de las
-f
opciones de generación de código son interesantes:La
-ftrapv
función hará que el programa aborte en el desbordamiento de enteros con signo (formalmente "comportamiento indefinido" en C).-fverbose-asm
es útil si está compilando-S
para examinar la salida del ensamblaje; agrega algunos comentarios informativos.-finstrument-functions
agrega código para llamar a funciones de creación de perfiles proporcionadas por el usuario en cada punto de entrada y salida de funciones.fuente
-ftrapv
, eche un vistazo aquí stackoverflow.com/questions/20851061/… .. parece que hay un error que espera mucho tiempo para ser reparado.Aquí están los míos:
-Wextra
,-Wall
: esencial.-Wfloat-equal
: útil porque generalmente probar números de coma flotante para determinar la igualdad es malo.-Wundef
: advierte si un identificador no inicializado se evalúa en una#if
directiva.-Wshadow
: advierte cuando una variable local sombrea otra variable local, parámetro o variable global o cuando una función incorporada está sombreada.-Wpointer-arith
: advierte si algo depende del tamaño de una función o devoid
.-Wcast-align
: avisa cada vez que se lanza un puntero de modo que se aumenta la alineación requerida del objetivo. Por ejemplo, advierta sichar *
se emite unint *
en máquinas en las que solo se puede acceder a los enteros en límites de dos o cuatro bytes.-Wstrict-prototypes
: advierte si una función se declara o define sin especificar los tipos de argumento.-Wstrict-overflow=5
: advierte sobre casos en los que el compilador se optimiza en base al supuesto de que no se produce un desbordamiento firmado. (El valor 5 puede ser demasiado estricto, consulte la página del manual).-Wwrite-strings
: proporcione a las constantes de cadena laconst char[
longitud del tipo]
para que al copiar la dirección de uno en un noconst char *
puntero se obtenga una advertencia.-Waggregate-return
: advierte si alguna función que devuelve estructuras o uniones se define o llama.-Wcast-qual
: advierte cada vez que se lanza un puntero para eliminar un calificador de tipo del tipo de destino * .-Wswitch-default
: advierte siempre que unaswitch
declaración no tenga undefault
caso * .-Wswitch-enum
: advierte cuando unaswitch
instrucción tiene un índice de tipo enumerado y carececase
de uno para uno o más de los códigos nombrados de esa enumeración * .-Wconversion
: advierte sobre conversiones implícitas que pueden alterar un valor * .-Wunreachable-code
: advierte si el compilador detecta que el código nunca se ejecutará * .Los marcados * a veces dan demasiadas advertencias espurias, por lo que las uso según sea necesario.
fuente
-Wformat=2
: Comprobaciones de formato adicionales en las funciones printf / scanf.-Wall
?-Wwrite-strings
porque lo odio mucho.-Wwrite-strings
específicamente dice que no es parte de-Wall
: gcc.gnu.org/onlinedocs/gcc/… . ¿Quizás algo más en su configuración está configurando esa bandera? ¿O tal vez estás compilando C ++?Siempre use
-O
o superior (-O1
,-O2
,-Os
, etc.). En el nivel de optimización predeterminado, gcc busca la velocidad de compilación y no hace suficiente análisis para advertir sobre cosas como variables unitarias.Considere hacer una
-Werror
política, ya que las advertencias que no detienen la compilación tienden a ser ignoradas.-Wall
prácticamente enciende las advertencias que muy probablemente sean errores.Las advertencias incluidas en
-Wextra
tienden a marcar códigos comunes y legítimos. Pueden ser útiles para las revisiones de código (aunque los programas estilo pelusa encuentran que muchas más trampas son más flexibles), pero no los activaría para el desarrollo normal.-Wfloat-equal
es una buena idea si los desarrolladores del proyecto no están familiarizados con el punto flotante, y una mala idea si lo están.-Winit-self
es útil; Me pregunto por qué no está incluido-Wuninitialized
.-Wpointer-arith
es útil si tiene un código mayormente portátil con el que no funciona-pedantic
.fuente
Esto deja atrás los resultados del preprocesador y el ensamblaje.
La fuente preprocesada es útil para depurar macros.
El ensamblaje es útil para determinar qué optimizaciones entraron en vigencia. Por ejemplo, es posible que desee verificar que GCC está haciendo la optimización de llamadas de cola en algunas funciones recursivas, ya que sin ella puede desbordar la pila.
fuente
Me sorprende que nadie haya dicho esto todavía: el indicador más útil en lo que a mí respecta es
-g
que coloca la información de depuración en el ejecutable para que pueda depurarla y pasar por la fuente (a menos que sea competente y lea el ensamblaje y como elstepi
comando) de un programa mientras se está ejecutando.fuente
-fmudflap : agrega comprobaciones de tiempo de ejecución a todas las operaciones de puntero arriesgadas para detectar UB. Esto efectivamente inmuniza su programa nuevamente desbordamientos de búfer y ayuda a atrapar todo tipo de punteros colgantes.
Aquí hay una demostración:
fuente
-fmudflap
ya no es compatible desde GCC 4.9, obtieneswarning: switch '-fmudflap' is no longer supported
. Fue reemplazado por AddressSanitizer.No está realmente relacionado con C / C ++, pero de todos modos es útil:
Ponga todos los indicadores buenos anteriores (que todos han especificado) en un 'archivo', y use este indicador anterior para usar todos los indicadores en ese archivo juntos.
p.ej:
Archivo: compilerFlags
Luego compila:
fuente
-march=native
para producir código optimizado para la plataforma (= chip) en la que está compilandofuente
Si necesita conocer los indicadores del preprocesador predefinidos por el compilador:
fuente
No es realmente útil para detectar errores, pero la
-masm=intel
opción rara vez mencionada hace que el uso-S
para inspeccionar la salida del ensamblaje sea mucho, mucho mejor.La sintaxis de ensamblaje de AT&T me duele demasiado la cabeza.
fuente
Mi archivo MAKE típicamente contiene
La más importante de estas opciones se ha discutido antes, por lo que señalaré las dos características que aún no se han señalado:
A pesar de que estoy trabajando en una base de código que debe ser C simple para la portabilidad a alguna plataforma que todavía no tiene un compilador de C ++ decente, hago una compilación "extra" con el compilador de C ++ (además del compilador de C). Eso tiene 3 beneficios:
Sí, soy una Pollyanna irremediablemente optimista que sigue pensando que seguramente en cualquier mes una plataforma será declarada obsoleta o obtendrá un compilador decente de C ++, y finalmente podremos cambiar a C ++. En mi opinión, es inevitable: la única pregunta es si eso sucede antes o después de que la gerencia finalmente les eche a todos un pony. :-)
fuente
fuente
-Wold-style-definition
si tiene que lidiar con reincidentes que piensan que las funciones de estilo K&R son una buena idea, incluso con declaraciones prototipadas. (Tengo que tratar con personas así. Realmente me molesta cuando encuentro un nuevo código escrito en K&R. Ya es bastante malo tener cosas de K&R heredadas que no están arregladas, ¡pero un código nuevo! ¡Grump!)Aquí hay una gran bandera que no se ha mencionado:
Dar un error cada vez que se utiliza una función antes de ser declarada.
fuente
El manual está lleno de banderas interesantes con buenas descripciones. Sin embargo, -Wall probablemente hará que gcc sea lo más detallado posible. Si desea datos más interesantes, debería echar un vistazo a valgrind o alguna otra herramienta para verificar errores.
fuente
man gcc | nl
reporta más de 11000 líneas. ¡Eso es más que la infame página debash
manual!Bueno, también
-Wextra
debería ser estándar.-Werror
convierte las advertencias en errores (que pueden ser muy molestos, especialmente si compila sin ellos-Wno-unused-result
).-pedantic
en combinación constd=c89
le da advertencias adicionales si utiliza las funciones C99.Pero eso es todo. No puede sintonizar un compilador de C en algo más de ahorro de texto que C en sí.
fuente
-M*
familia de opciones.Estos le permiten escribir archivos que determinan automáticamente de qué archivos de encabezado deberían depender sus archivos fuente c o c ++. GCC generará archivos de creación con esta información de dependencia y luego los incluirá desde su archivo de creación principal.
Aquí hay un ejemplo de un archivo MAKE extremadamente genérico que usa -MD y -MP que compilará un directorio lleno de archivos de origen y encabezado de c ++, y descubrirá todas las dependencias automáticamente:
Aquí hay una publicación de blog que lo analiza con más profundidad: http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html
fuente
Existe
-Werror
, que trata todas las advertencias como errores y detiene la compilación. Lagcc
página del manual explica cada cambio de línea de comando para su compilador.fuente
gcc
indicadores pueden ser diferentes entre los suyos y cualquier vínculo que alguien sugiera. Esta es la razón por la cual se suministran páginas de manual con su software.-Wfloat-equal
De: http://mces.blogspot.com/2005/07/char-const-argv.html
fuente
Encontré este hilo buscando una bandera para solucionar un problema específico, no lo veo aquí, así que agregaré uno que me estaba confundiendo en mi publicación :
La
-Wformat=2
banderaY la parte realmente importante al respecto ( según el manual de GCC ):
Entonces, solo porque tienes
-Wall
no significa que lo tengas todo. ;)fuente
A veces lo uso
-s
para un ejecutable mucho más pequeño:Fuente: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
fuente
strip
su binario, de esta manera puede tener un binario con información de depuración, eliminarlo más tarde para su distribución.strip
también funciona , pero-s
puede ser más rápido y fácil, aunque no es tan elaborado como correrstrip
Si bien esta respuesta puede estar un poco fuera de tema y la pregunta es un digno +1 para mí, ya que
hay una herramienta que debería detectar TODOS los errores y posibles errores que pueden no ser obvios, hay una férula que, en mi humilde opinión, hace un mejor trabajo para detectar errores en comparación con gcc o cualquier otro compilador. Esa es una herramienta digna de tener en su caja de herramientas.La comprobación estática a través de una herramienta tipo pelusa, como la férula, debería haber sido parte de una cadena de herramientas del compilador.
fuente
Además
-Wall
, la opción-W
o-Wextra
(-W
funciona con versiones anteriores de gcc así como con las más nuevas; las versiones más recientes admiten el nombre alternativo-Wextra
, que significa lo mismo, pero es más descriptivo) habilita varias advertencias adicionales.También hay aún más advertencias que no están habilitadas por ninguno de ellos, generalmente para cosas que son más cuestionables. El conjunto de opciones disponibles depende de la versión de gcc que esté utilizando; consulte
man gcc
oinfo gcc
para obtener más información, o consulte la documentación en línea para la versión de gcc en particular que le interese. Y-pedantic
emite todas las advertencias requeridas por el estándar particular que se está utilizando (que depende en otras opciones como-std=xxx
o-ansi
) y se queja sobre el uso de extensiones gcc.-Werror
convierte todas las advertencias en errores. Sin embargo, no creo que gcc le permita hacer eso selectivamente para advertencias particulares.Probablemente encontrará que tiene que ser selectivo sobre qué advertencias están habilitadas para cada proyecto (especialmente si lo usa
-Werror
), ya que los archivos de encabezado de bibliotecas externas pueden disparar algunas de ellas. (-pedantic
en particular tiende a ser inútil a este respecto, en mi experiencia).fuente
-Werror=some-warning
.-Wmissing-prototypes
: Si una función global se define sin una declaración de prototipo previa.-Wformat-security
: Advierte sobre los usos de las funciones de formato que representan posibles problemas de seguridad. En la actualidad, esto advierte sobre llamadasprintf
yscanf
funciones donde la cadena de formato no es un literal de cadena y no hay argumentos de formatofuente
-Werror=return-type
: Aplicar error cuando la función no tiene retorno en gcc. Está/we4716
en Visual Studio.-Werror=implicit-function-declaration
: Aplicar error cuando la función se utiliza sin definido / no incluido. Está/we4013
en Visual Studio.-Werror=incompatible-pointer-types
: Enfore error cuando el tipo de un puntero no coincide con el tipo de puntero esperado. Está/we4133
en Visual Studio.En realidad, me gustaría mantener mi código C multiplataforma, y uso CMake, y pongo los cflags proporcionados en CMakeLists.txt como:
fuente