Au-delà des paramètres -Wall
et des paramètres -std=XXX
, quels sont les autres indicateurs de compilateur vraiment utiles, mais moins connus, qui peuvent être utilisés en C?
Je suis particulièrement intéressé par les avertissements supplémentaires et / ou par la transformation des avertissements en erreurs dans certains cas afin de minimiser absolument toute incompatibilité de type accidentelle.
c
gcc
compiler-flags
Matt Joiner
la source
la source
-save-temps
,-Wshadow
et-fmudflap
c'était les plus belles découvertes que je ne connaissais pas, merci à tous.gcc -c [flags-go-here] -o myprog.o myprog.c
pour compiler (pas lier) un programme C.Réponses:
Plusieurs
-f
options de génération de code sont intéressantes:La
-ftrapv
fonction provoquera l'arrêt du programme en cas de dépassement d'entier signé (formellement «comportement indéfini» en C).-fverbose-asm
est utile si vous compilez avec-S
pour examiner la sortie de l'assembly - il ajoute quelques commentaires informatifs.-finstrument-functions
ajoute du code pour appeler les fonctions de profilage fournies par l'utilisateur à chaque entrée de fonction et point de sortie.la source
-ftrapv
, jetez un œil ici stackoverflow.com/questions/20851061/… .. il semble qu'il y ait un bogue qui attend depuis longtemps d'être corrigé.Voici les miens:
-Wextra
,-Wall
: indispensable.-Wfloat-equal
: utile car il est généralement mauvais de tester l'égalité des nombres à virgule flottante.-Wundef
: avertit si un identifiant non initialisé est évalué dans une#if
directive.-Wshadow
: avertit chaque fois qu'une variable locale masque une autre variable locale, un paramètre ou une variable globale ou chaque fois qu'une fonction intégrée est masquée.-Wpointer-arith
: avertir si quelque chose dépend de la taille d'une fonction ou devoid
.-Wcast-align
: avertit chaque fois qu'un pointeur est lancé de telle sorte que l'alignement requis de la cible est augmenté. Par exemple, avertissez si achar *
est converti en unint *
sur des machines où les entiers ne sont accessibles qu'à des limites de deux ou quatre octets.-Wstrict-prototypes
: avertit si une fonction est déclarée ou définie sans spécifier les types d'arguments.-Wstrict-overflow=5
: avertit des cas où le compilateur optimise en partant de l'hypothèse que le débordement signé ne se produit pas. (La valeur 5 peut être trop stricte, voir la page de manuel.)-Wwrite-strings
: donnez aux constantes de chaîne laconst char[
longueur du type]
pour que la copie de l'adresse de l'une dans un non-const char *
pointeur obtienne un avertissement.-Waggregate-return
: avertit si des fonctions qui renvoient des structures ou des unions sont définies ou appelées.-Wcast-qual
: avertit chaque fois qu'un pointeur est casté pour supprimer un qualificateur de type du type cible * .-Wswitch-default
: avertir chaque fois qu'uneswitch
instruction n'a pas dedefault
cas * .-Wswitch-enum
: avertit chaque fois qu'uneswitch
instruction a un index de type énuméré et n'a pas decase
pour un ou plusieurs des codes nommés de cette énumération * .-Wconversion
: avertit des conversions implicites qui peuvent modifier une valeur * .-Wunreachable-code
: avertit si le compilateur détecte que le code ne sera jamais exécuté * .Ceux marqués * donnent parfois trop de faux avertissements, je les utilise donc au besoin.
la source
-Wformat=2
: Vérifications de format supplémentaire sur les fonctions printf / scanf.-Wall
?-Wwrite-strings
parce que je le déteste tellement.-Wwrite-strings
précise que cela ne fait pas partie de-Wall
: gcc.gnu.org/onlinedocs/gcc/… . Peut-être que quelque chose d'autre dans votre configuration définit cet indicateur? Ou peut-être que vous compilez C ++?Toujours utiliser
-O
ou au- dessus (-O1
,-O2
,-Os
, etc.). Au niveau d'optimisation par défaut, gcc opte pour la vitesse de compilation et ne fait pas assez d'analyse pour avertir de choses comme les variables unifiées.Pensez à établir une
-Werror
politique, car les avertissements qui n'arrêtent pas la compilation ont tendance à être ignorés.-Wall
active à peu près les avertissements qui sont très probablement des erreurs.Les avertissements inclus dans
-Wextra
ont tendance à signaler le code commun et légitime. Ils peuvent être utiles pour les révisions de code (bien que les programmes de style lint trouvent que beaucoup plus de pièges sont plus flexibles), mais je ne les activerais pas pour un développement normal.-Wfloat-equal
est une bonne idée si les développeurs du projet ne sont pas familiers avec la virgule flottante, et une mauvaise idée s'ils le sont.-Winit-self
est utile; Je me demande pourquoi ce n'est pas inclus dans-Wuninitialized
.-Wpointer-arith
est utile si vous avez du code principalement portable qui ne fonctionne pas avec-pedantic
.la source
Cela laisse derrière les résultats du préprocesseur et de l'assemblage.
La source prétraitée est utile pour le débogage des macros.
L'assemblage est utile pour déterminer quelles optimisations sont entrées en vigueur. Par exemple, vous voudrez peut-être vérifier que GCC fait l'optimisation des appels de queue sur certaines fonctions récursives, car sans cela, vous pouvez potentiellement déborder la pile.
la source
Je suis surpris que personne n'ait encore dit cela - l'indicateur le plus utile en ce qui me concerne est celui
-g
qui place les informations de débogage dans l'exécutable de sorte que vous puissiez le déboguer et parcourir la source (sauf si vous êtes compétent et lisez l'assembly et comme lastepi
commande) d'un programme pendant son exécution.la source
-fmudflap - ajoute des vérifications d'exécution à toutes les opérations de pointeur à risque pour attraper UB. Cela immunise efficacement votre programme contre les débordements de tampon et aide à attraper toutes sortes de pointeurs pendantes.
Voici une démo:
la source
-fmudflap
n'est plus pris en charge depuis GCC 4.9, vous obtenezwarning: switch '-fmudflap' is no longer supported
. Il a été remplacé par AddressSanitizer.Pas vraiment lié à C / C ++, mais utile quand même:
Mettez tous les bons indicateurs ci-dessus (que vous avez tous spécifiés) dans un 'fichier' et utilisez cet indicateur ci-dessus pour utiliser tous les indicateurs de ce fichier ensemble.
par exemple:
Fichier: compilerFlags
Puis compilez:
la source
-march=native
pour produire du code optimisé pour la plateforme (= puce) sur laquelle vous compilezla source
Si vous avez besoin de connaître les indicateurs de préprocesseur qui sont prédéfinis par le compilateur:
la source
Ce n'est pas vraiment utile pour détecter les erreurs, mais l'
-masm=intel
option rarement mentionnée rend l'utilisation-S
d'inspecter la sortie de l'assemblage beaucoup plus agréable.La syntaxe d'assemblage AT&T me fait trop mal à la tête.
la source
Mon makefile contient généralement
Les plus importantes de ces options ont déjà été discutées, je vais donc souligner les deux fonctionnalités qui n'ont pas encore été signalées:
Même si je travaille sur une base de code qui doit être en C pur pour la portabilité vers une plate-forme qui n'a toujours pas de compilateur C ++ décent, je fais une compilation "supplémentaire" avec le compilateur C ++ (en plus du compilateur C). Cela présente 3 avantages:
Oui, je suis un Pollyanna désespérément optimiste qui continue à penser que sûrement un mois maintenant que une plate - forme sera soit déclarée obsolète, ou gagner un compilateur C ++ décent, et nous pouvons enfin passer à C ++. Dans mon esprit, c'est inévitable - la seule question est de savoir si cela se produit avant ou après que la direction délivre enfin à tout le monde un poney. :-)
la source
la source
-Wold-style-definition
si vous avez affaire à des récidivistes qui pensent que les fonctions de style K&R sont une bonne idée, même avec des déclarations prototypées. (Je dois faire face à des gens comme ça. Cela m'énerve vraiment quand je trouve un nouveau code écrit en K&R. C'est déjà assez mauvais d'avoir des éléments K&R hérités qui ne sont pas corrigés, mais un nouveau code! Grump !!!)Voici un excellent drapeau qui n'a pas été mentionné:
Donne une erreur chaque fois qu'une fonction est utilisée avant d'être déclarée.
la source
Le manuel regorge d'indicateurs intéressants avec de bonnes descriptions. Cependant, -Wall rendra probablement gcc aussi verbeux que possible. Si vous voulez des données plus intéressantes, vous devriez jeter un oeil à valgrind ou à un autre outil pour vérifier les erreurs.
la source
man gcc | nl
rapporte plus de 11 000 lignes. C'est plus que la fameusebash
page de manuel!Eh bien, cela
-Wextra
devrait aussi être standard.-Werror
transforme les avertissements en erreurs (ce qui peut être très ennuyeux, surtout si vous compilez sans-Wno-unused-result
).-pedantic
en combinaison avecstd=c89
vous donne des avertissements supplémentaires si vous utilisez les fonctionnalités du C99.Mais c'est à peu près tout. Vous ne pouvez pas régler un compilateur C en quelque chose de plus de sauvegarde de type que C lui-même.
la source
-M*
famille d'options.Ceux-ci vous permettent d'écrire des fichiers de création qui déterminent automatiquement de quels fichiers d'en-tête vos fichiers source c ou c ++ devraient dépendre. GCC générera des fichiers make avec ces informations de dépendance, puis vous les incluerez à partir de votre fichier make principal.
Voici un exemple de makefile extrêmement générique utilisant -MD et -MP qui compilera un répertoire plein de fichiers source et d'en-tête C ++, et déterminera automatiquement toutes les dépendances:
Voici un article de blog qui en parle plus en profondeur: http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html
la source
Il existe
-Werror
, qui traite tous les avertissements comme des erreurs et arrête la compilation. Lagcc
page de manuel explique chaque commutateur de ligne de commande pour votre compilateur.la source
gcc
indicateurs peuvent être différents entre le vôtre et le lien que quelqu'un pourrait suggérer. C'est pourquoi des pages de manuel sont fournies avec votre logiciel.-Wfloat-equal
De: http://mces.blogspot.com/2005/07/char-const-argv.html
la source
J'ai trouvé ce fil à la recherche d'un indicateur pour résoudre un problème spécifique, je ne le vois pas ici, je vais donc en ajouter un qui me stoppait juste sur mon message :
Le
-Wformat=2
drapeauEt la partie vraiment importante à ce sujet ( selon le manuel GCC ):
Donc, ce
-Wall
n'est pas parce que vous avez tout ce que vous avez. ;)la source
J'utilise parfois
-s
pour un exécutable beaucoup plus petit:Source: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
la source
strip
sur votre binaire, de cette façon vous pouvez avoir un binaire avec des informations de débogage, supprimez-le plus tard pour la distribution.strip
fonctionne aussi mais-s
peut être plus rapide et plus facile, même si ce n'est pas aussi élaboré que de courirstrip
Bien que cette réponse puisse être légèrement hors sujet et que la question soit un +1 digne de ma part, puisque
il y a un outil qui devrait attraper TOUTES les erreurs et les erreurs potentielles qui peuvent ne pas être évidentes, il y a une attelle qui, à mon humble avis, fait un travail bien meilleur pour attraper les erreurs par rapport à gcc ou à tout autre compilateur d'ailleurs. C'est un outil digne d'avoir dans votre coffre à outils.La vérification statique via un outil de type lint tel que splint, aurait dû faire partie d'une chaîne d'outils de compilateur.
la source
En plus de
-Wall
, l' option-W
ou-Wextra
(-W
fonctionne avec les anciennes versions de gcc ainsi que les plus récentes; les versions plus récentes prennent en charge le nom alternatif-Wextra
, qui signifie la même chose, mais est plus descriptif) permet divers avertissements supplémentaires.Il y a aussi encore plus d'avertissements qui ne sont activés par aucun de ceux-ci, généralement pour des choses qui sont plus douteuses. L'ensemble des options disponibles dépend de la version de gcc que vous utilisez - consultez
man gcc
ouinfo gcc
pour plus de détails, ou consultez la documentation en ligne de la version de gcc qui vous intéresse. Et-pedantic
émet tous les avertissements requis par la norme particulière utilisée (ce qui dépend sur d'autres options telles que-std=xxx
ou-ansi
) et se plaint de l'utilisation des extensions gcc.-Werror
transforme tous les avertissements en erreurs. Je ne pense pas que gcc vous permette de faire cela de manière sélective pour des avertissements particuliers, cependant.Vous constaterez probablement que vous devez être sélectif sur les avertissements activés par projet (surtout si vous utilisez
-Werror
), car les fichiers d'en-tête de bibliothèques externes peuvent en déclencher certains. (-pedantic
en particulier, a tendance à ne pas être utile à cet égard, d'après mon expérience.)la source
-Werror=some-warning
.-Wmissing-prototypes
: Si une fonction globale est définie sans déclaration de prototype préalable.-Wformat-security
: Avertit des utilisations des fonctions de formatage qui représentent des problèmes de sécurité possibles. À l'heure actuelle, cela avertit des appels àprintf
et desscanf
fonctions où la chaîne de format n'est pas une chaîne littérale et il n'y a pas d'arguments de formatla source
-Werror=return-type
: Appliquer une erreur lorsque la fonction n'a pas de retour dans gcc. C'est/we4716
dans Visual Studio.-Werror=implicit-function-declaration
: Appliquer une erreur lorsque la fonction est utilisée sans définie / non incluse. C'est/we4013
dans Visual Studio.-Werror=incompatible-pointer-types
: Erreur Enfore lorsque le type d'un pointeur ne correspond pas au type de pointeur attendu. C'est/we4133
dans Visual Studio.En fait, j'aimerais garder mon code C multiplateforme, et j'utilise CMake, et je mets les cflags fournis dans CMakeLists.txt comme:
la source