Banderas GCC útiles para C


Más allá de establecer -Wall, y establecer -std=XXX, ¿qué otros indicadores de compilador realmente útiles, pero menos conocidos, existen para usar en C?

Estoy particularmente interesado en cualquier advertencia adicional, y/o y convertir las advertencias en errores en algunos casos para minimizar absolutamente cualquier desajuste de tipo accidental.

Author: Matt Joiner, 2010-07-31

23 answers

Varias de las opciones de generación de código -f son interesantes:

  • La función -ftrapv hará que el programa aborteen caso de desbordamiento de enteros con signo (formalmente "comportamiento indefinido" en C).

  • -fverbose-asm es útil si está compilando con -S para examinar la salida del ensamblado: agrega algunos comentarios informativos.

  • -finstrument-functions agrega código para llamar a las funciones de generación de perfiles suministradas por el usuario en cada punto de entrada y salida de la función.

 62
Author: caf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-31 01:35:14

Aquí están los míos:

  • -Wextra, -Wall: esencial.
  • -Wfloat-equal: útil porque usualmente probar números de coma flotante para la igualdad es malo.
  • -Wundef: avisa si se evalúa un identificador no inicializado en una directiva #if.
  • -Wshadow: avisa cuando una variable local ensombrece otra variable local, parámetro o variable global o cuando se ensombrece una función integrada.
  • -Wpointer-arith: advertir si algo depende del tamaño de una función o de void.
  • -Wcast-align: avisa cada vez que se lanza un puntero de forma que aumente la alineación requerida del objetivo. Por ejemplo, advierta si un char * se convierte en un int * en máquinas donde solo se puede acceder a enteros en límites de dos o cuatro bytes.
  • -Wstrict-prototypes: avisa si una función es declarada o definida sin especificar los tipos de argumento.
  • -Wstrict-overflow=5: advierte sobre los casos en los que el compilador optimiza basándose en la suposición de que no se produce desbordamiento firmado. (El valor 5 puede ser demasiado estricto, consulte la página de manual.)
  • -Wwrite-strings: dar constantes de cadena el tipo const char[longitud] así que copiar la dirección de uno en un puntero no-const char * recibirá una advertencia.
  • -Waggregate-return: avisa si cualquier función que devuelva estructuras o uniones está definida o llamada.
  • -Wcast-qual: avisa cada vez que se lanza un puntero para eliminar un calificador de tipo del tipo de destino*.
  • -Wswitch-default: advertir cuando una declaración switch no tiene una default caso*.
  • -Wswitch-enum: advertir cuando una instrucción switch tiene un índice de tipo enumerado y carece de un case para uno o más de los códigos nombrados de esa enumeración*.
  • -Wconversion: advertir sobre conversiones implícitas que pueden alterar un valor*.
  • -Wunreachable-code: avisa si el compilador detecta que el código nunca será ejecutado*.

Los marcados * a veces doy demasiadas advertencias falsas, así que las uso según sea necesario base.

 129
Author: Alok Singhal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-31 02:10:52

Utilice siempre -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 las variables unitializadas.

Considere hacer una política -Werror, ya que las advertencias que no detienen la compilación tienden a ser ignoradas.

-Wall prácticamente activa las advertencias que son muy probables que sean errores.

Las advertencias incluidas en -Wextra tienden a marcar código común y legítimo. Pueden ser útil para revisiones de código (aunque los programas de estilo lint encuentran muchas más trampas y son más flexibles), pero no las activaría para un 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 en -Wuninitialized.

-Wpointer-arith es útil si tiene código mayormente portable que no funciona con -pedantic.

 50
Author: Gilles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 22:29:27
-save-temps

Esto deja atrás los resultados del preprocesador y el ensamblaje.

El código fuente preprocesado es útil para depurar macros.

El ensamblado es útil para determinar qué optimizaciones entraron en vigor. 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 potencialmente la pila.

 37
Author: catphive,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-06 21:50:44

Me sorprende que nadie haya dicho esto todavía - la bandera más útil en lo que a mí respecta es -g que pone la información de depuración en el ejecutable de modo que se puede depurar y paso a través de la fuente (a menos que seas competente y la lectura de montaje y como el comando stepi) de un programa mientras se está ejecutando.

 35
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 22:23:27

-fmudflap adds agrega comprobaciones de tiempo de ejecución a todas las operaciones de puntero riesgosas para capturar UB. Esto inmuniza eficazmente su programa de nuevo desbordamientos de búfer y ayuda a atrapar todo tipo de punteros colgantes.

Aquí hay una demostración:

$ cat mf.c 
int main()
{
 int a[10];
 a[10]=1; // <-- o noes, line 4
}

$ gcc -fmudflap mf.c -lmudflap
$ ./a.out 
*******
mudflap violation 1 (check/write): time=1280862302.170759 ptr=0x7fff96eb3d00 size=44
pc=0x7f3a575503c1 location=`mf.c:4:2 (main)'
      /usr/lib/libmudflap.so.0(__mf_check+0x41) [0x7f3a575503c1]
      ./a.out(main+0x90) [0x400a54]
      /lib/libc.so.6(__libc_start_main+0xfd) [0x7f3a571e2c4d]
Nearby object 1: checked region begins 0B into and ends 4B after
mudflap object 0xf9c560: name=`mf.c:3:6 (main) a'
bounds=[0x7fff96eb3d00,0x7fff96eb3d27] size=40 area=stack check=0r/3w liveness=3
alloc time=1280862302.170749 pc=0x7f3a57550cb1
number of nearby objects: 1
 35
Author: Nordic Mainframe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-03 19:07:51

No está realmente relacionado con C / C++, pero es útil de todos modos :

@file

Ponga todas las buenas banderas anteriores (que todos han especificado) en un 'archivo', y use esta bandera anterior para usar todas las banderas en ese archivo juntas.

Eg:

Archivo: compilerFlags

- Muro

- std = c99

- Wextra

Luego compila:

gcc yourSourceFile @compilerFlags
 16
Author: Amit Tomar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-15 06:47:00

-march=native para producir código optimizado para la plataforma (=chip) en la que está compilando

 15
Author: Jens Gustedt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-31 07:33:17

Si necesita conocer los indicadores del preprocesador que están predefinidos por el compilador:

echo | gcc -E -dM -
 13
Author: sizzzzlerz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-31 13:46:59

No es realmente útil para detectar errores, pero la rara vez mencionada opción -masm=intel hace que usar -S para inspeccionar la salida del ensamblaje sea mucho, mucho más agradable.

La sintaxis del ensamblado de AT&T me duele demasiado la cabeza.

 13
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-04 06:15:31

Mi makefile normalmente contiene

  CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb
  ...
  g++ $(CFLAGS) -o junk $<
  gcc $(CFLAGS) -o $@ $<
  rm -f junk

Las opciones más importantes ya se han discutido antes, así que señalaré las dos características que aún no se han señalado:

Aunque estoy trabajando en una base de código que necesita ser C simple para portabilidad a alguna plataforma que todavía no tiene un compilador C++ decente, hago una compilación "extra" con el compilador C++ (además del compilador C). Eso tiene 3 beneficios:

  1. el compilador de C++ ocasionalmente me da mejores mensajes de advertencia que el compilador de C.
  2. El compilador de C++ acepta la opción-Weffc++, que ocasionalmente me da algunos consejos útiles, que me perdería si solo lo compilara en C.
  3. Puedo mantener el código relativamente fácil de portar a C++, evitando algunas condiciones de límite donde el código C simple es código C++ no válido (como definir una variable llamada "bool").

Sí, soy una Pollyanna irremediablemente optimista que sigue pensando seguramente cualquier mes en que una plataforma sea declarada obsoleta, o obtenga un compilador de C++ decente, y finalmente podamos cambiar a C++. En mi mente, es inevitable the la única pregunta es si eso sucede antes o después de que la gerencia finalmente emita a todos un pony. :-)

 10
Author: David Cary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-14 01:23:07
-Wstrict-prototypes -Wmissing-prototypes
 9
Author: ninjalj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 22:32:46

Aquí hay una gran bandera que no se ha mencionado:

-Werror-implicit-function-declaration

Da un error cada vez que se usa una función antes de ser declarada.

 9
Author: Matt Joiner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-14 15:59:57
man gcc

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, debe echar un vistazo a valgrind o alguna otra herramienta para verificar errores.

 8
Author: Johan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 22:09:07

Bueno, -Wextra también debería ser estándar. -Werrorconvierte las advertencias en errores (que pueden ser muy molestos, especialmente si compilas sin -Wno-unused-result). -pedantic en combinación con std=c89 le da advertencias adicionales si utiliza características de C99.

Pero eso es todo. No se puede sintonizar un compilador de C en algo más guardado de tipo que el propio C.

 6
Author: RWS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 22:14:04

Existe -Werror, que trata todas las advertencias como errores y detiene la compilación. Las gcc la página de manual explica cada cambio de línea de comandos para su compilador.

 6
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-14 23:12:21

-M* familia de opciones.

Estos le permiten escribir archivos make que automáticamente averiguan de qué archivos de encabezado deben depender sus archivos fuente de c o c++. GCC generará archivos make con esta información de dependencia, y luego los incluirá desde su archivo make principal.

Aquí hay un ejemplo de un makefile extremadamente genérico usando-MD y-MP que compilará un directorio lleno de archivos de código fuente y encabezado de c++, y averiguará todas las dependencias automáticamente:

CPPFLAGS += -MD -MP                                         
SRC = $(wildcard *.cpp)                                                       

my_executable: $(SRC:%.cpp=%.o)                                                        
        g++ $(LDFLAGS) -o $@ $^                                               

-include $(SRC:%.cpp=%.d)

Aquí hay una entrada de blog que lo discute con más profundidad: http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html

 4
Author: catphive,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-06 21:47:37

-Wfloat-equal

De: http://mces.blogspot.com/2005/07/char-const-argv.html

Una de las otras nuevas advertencias que me gustan es la-Wfloat-equal. Que uno advierte cada vez que [tiene] un número de coma flotante en una condición de igualdad. Que briliant! Si tiene todos programados un algoritmo de gráficos por computadora o (peor:) geometría computacional, sabe que no hay dos flotadores que coincidan con la igualdad...

 4
Author: stud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-26 14:47:42

Encontré este hilo buscando una bandera para solucionar un problema específico, no lo veo aquí, así que agregaré uno que me estaba pegando en mi mensaje :

La bandera -Wformat=2

-Wformat => Comprobar llamadas a printf y scanf, etc., para asegurarse de que los argumentos suministrados tienen tipos apropiados para la cadena de formato especificada...

Y la parte realmente importante al respecto ( según el manual del CCG):

-Wformat está incluido en -Wall. Para un mayor control sobre algunos aspectos de la comprobación de formato, las opciones -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, y -Wformat=2 están disponibles, pero no se incluyen en la pared.`

Así que, solo porque tienes -Wall no significa que lo tienes todo. ;)

 4
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:42

A veces uso -s para un ejecutable mucho más pequeño:

-s
    Remove all symbol table and relocation information from the executable.

Fuente: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options

 3
Author: Vasiliy Sharapov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-31 00:38:41

Mientras que esta respuesta puede ser un poco fuera de tema y la pregunta es un digno +1 de mí, ya que

Estoy particularmente interesado en cualquier advertencia adicional, y/o y convertir las advertencias en errores en algunos casos para minimizar absolutamente cualquier desajuste de tipo accidental.
hay una herramienta que debería detectar TODOS los errores y los errores potenciales que pueden no ser obvios, hay férula que EN mi humilde opinión hace un mejor trabajo en la detección de errores en comparación con gcc o cualquier otro compilador para el caso. Esa es una herramienta digna de tener en su cofre de herramientas.

La comprobación estática a través de una herramienta tipo pelusa, como splint, debería haber sido parte de una cadena de herramientas del compilador.

 3
Author: t0mm13b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-09 15:04:13

Estoy particularmente interesado en cualquier advertencia adicional,{[15]]}

Además de -Wall, la opción -W o -Wextra (-W funciona con versiones anteriores de gcc, así como con versiones más recientes; 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 ninguna de ellas, generalmente para cosas que son más cuestionablemente malas. El el conjunto de opciones disponibles depende de la versión de gcc que esté utilizando: consulte man gcc o info gcc para obtener más detalles, 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 de otras opciones como -std=xxx o -ansi) y se queja sobre el uso de extensiones gcc.

Y / o y convertir las advertencias en errores en algunos casos para minimizar absolutamente cualquier accidente tipo desajustes.

-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 en cada proyecto (especialmente si usa -Werror), ya que los archivos de encabezado de bibliotecas externas pueden hacer tropezar algunas de ellas. (-pedantic en particular, tiende a ser inútil en este sentido, en mi experiencia.)

 2
Author: Matthew Slattery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 23:48:53
  • -Wmissing-prototypes: Si se define una función global sin una declaración de prototipo previa.
  • -Wformat-security: Advierte sobre el uso de funciones de formato que representan posibles problemas de seguridad. En la actualidad, esto advierte sobre las llamadas a las funciones printf y scanf donde la cadena de formato no es un literal de cadena y no hay argumentos de formato
 0
Author: Praveen Handigol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-02 18:11:53