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.
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.
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 devoid
. -
-Wcast-align
: avisa cada vez que se lanza un puntero de forma que aumente la alineación requerida del objetivo. Por ejemplo, advierta si unchar *
se convierte en unint *
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 tipoconst 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ónswitch
no tiene unadefault
caso*. -
-Wswitch-enum
: advertir cuando una instrucciónswitch
tiene un índice de tipo enumerado y carece de uncase
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.
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
.
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.
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.
-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
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
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
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 -
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.
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:
- el compilador de C++ ocasionalmente me da mejores mensajes de advertencia que el compilador de C.
- 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.
- 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. :-)
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
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.
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.
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. -Werror
convierte 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.
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.
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
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...
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 aprintf
yscanf
, 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. ;)
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
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.
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.)
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 funcionesprintf
yscanf
donde la cadena de formato no es un literal de cadena y no hay argumentos de formato
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