Welche anderen wirklich nützlichen, aber weniger bekannten Compiler-Flags gibt es neben dem Setzen -Wall
und Setzen -std=XXX
für die Verwendung in C?
Ich bin besonders an zusätzlichen Warnungen interessiert und / oder daran, Warnungen in einigen Fällen in Fehler umzuwandeln, um versehentliche Typinkongruenzen absolut zu minimieren.
c
gcc
compiler-flags
Matt Joiner
quelle
quelle
-save-temps
,-Wshadow
und-fmudflap
waren die größten Funde, von denen ich dank allem nichts wusste.gcc -c [flags-go-here] -o myprog.o myprog.c
, um ein C-Programm zu kompilieren (nicht zu verknüpfen).Antworten:
Einige der
-f
Optionen zur Codegenerierung sind interessant:Die
-ftrapv
Funktion bewirkt, dass das Programm bei einem vorzeichenbehafteten Ganzzahlüberlauf abgebrochen wird (formal "undefiniertes Verhalten" in C).-fverbose-asm
ist nützlich, wenn Sie mit kompilieren-S
, um die Assembly-Ausgabe zu untersuchen - es werden einige informative Kommentare hinzugefügt.-finstrument-functions
Fügt Code hinzu, um vom Benutzer bereitgestellte Profilierungsfunktionen an jedem Funktionsein- und -ausgangspunkt aufzurufen.quelle
-ftrapv
, tun Sie einen Blick hier haben stackoverflow.com/questions/20851061/... .. scheint , wie es lange einen Fehler wartet behoben.Hier sind meine:
-Wextra
,-Wall
: wesentlich.-Wfloat-equal
: nützlich, da das Testen von Gleitkommazahlen auf Gleichheit normalerweise schlecht ist.-Wundef
: warnen, wenn eine nicht initialisierte Kennung in einer#if
Direktive ausgewertet wird .-Wshadow
: warnen, wann immer eine lokale Variable eine andere lokale Variable, einen Parameter oder eine globale Variable beschattet oder wann immer eine integrierte Funktion beschattet wird.-Wpointer-arith
: warnen, wenn etwas von der Größe einer Funktion oder von abhängtvoid
.-Wcast-align
: warnen, wenn ein Zeiger so geworfen wird, dass die erforderliche Ausrichtung des Ziels erhöht wird. Zum Beispiel warnen , wenn einchar *
auf ein gegossen wirdint *
auf Maschinen , bei denen ganzen Zahlen können nur auf zwei oder vier Byte - Grenzen zugegriffen werden.-Wstrict-prototypes
: warn, wenn eine Funktion ohne Angabe der Argumenttypen deklariert oder definiert wird.-Wstrict-overflow=5
: warnt vor Fällen, in denen der Compiler unter der Annahme optimiert, dass kein signierter Überlauf auftritt. (Der Wert 5 ist möglicherweise zu streng, siehe Handbuchseite.)-Wwrite-strings
: Geben Sie Zeichenfolgenkonstanten dieconst char[
Typlänge an,]
damit beim Kopieren der Adresse von eins in einen Nichtzeigerconst char *
eine Warnung angezeigt wird.-Waggregate-return
: warnen, wenn Funktionen definiert oder aufgerufen werden, die Strukturen oder Gewerkschaften zurückgeben.-Wcast-qual
: warnen, wann immer ein Zeiger gesetzt wird, um ein Typqualifikationsmerkmal aus dem Zieltyp * zu entfernen .-Wswitch-default
: warnen, wenn eineswitch
Anweisung keinendefault
Fall hat * .-Wswitch-enum
: warnen, wenn eineswitch
Anweisung einen Index vom Typ Aufzählung hat undcase
für einen oder mehrere der genannten Codes dieser Aufzählung * kein Index vorhanden ist .-Wconversion
: warnt vor impliziten Konvertierungen, die einen Wert ändern können * .-Wunreachable-code
: warnen, wenn der Compiler feststellt, dass Code niemals ausgeführt wird * .Die mit * gekennzeichneten geben manchmal zu viele falsche Warnungen aus, daher verwende ich sie nach Bedarf.
quelle
-Wformat=2
: Zusätzliche Formatprüfungen für printf / scanf-Funktionen.-Wall
?-Wwrite-strings
weil ich es so sehr hasse.-Wwrite-strings
besagt jedoch ausdrücklich, dass es nicht Teil von-Wall
: gcc.gnu.org/onlinedocs/gcc/… ist . Vielleicht setzt etwas anderes in Ihrem Setup dieses Flag? Oder kompilieren Sie vielleicht C ++?Verwenden Sie immer
-O
oder über (-O1
,-O2
,-Os
, etc.). Auf der Standardoptimierungsstufe setzt gcc auf Kompilierungsgeschwindigkeit und führt nicht genügend Analysen durch, um vor Dingen wie einheitlichen Variablen zu warnen.Erwägen Sie,
-Werror
Richtlinien zu erstellen, da Warnungen, die die Kompilierung nicht stoppen, häufig ignoriert werden.-Wall
Aktiviert so ziemlich die Warnungen, bei denen es sich sehr wahrscheinlich um Fehler handelt.In enthaltene Warnungen kennzeichnen in der
-Wextra
Regel allgemeinen, legitimen Code. Sie können für Codeüberprüfungen nützlich sein (obwohl Programme im Fusselstil viel mehr Fallstricke flexibler finden), aber ich würde sie für die normale Entwicklung nicht aktivieren.-Wfloat-equal
ist eine gute Idee, wenn die Entwickler des Projekts mit Gleitkommazahlen nicht vertraut sind, und eine schlechte Idee, wenn sie es sind.-Winit-self
ist nützlich; Ich frage mich, warum es nicht in enthalten ist-Wuninitialized
.-Wpointer-arith
ist nützlich, wenn Sie meistens portablen Code haben, der nicht funktioniert-pedantic
.quelle
Dies hinterlässt die Ergebnisse des Präprozessors und der Baugruppe.
Die vorverarbeitete Quelle ist nützlich zum Debuggen von Makros.
Die Assembly ist nützlich, um festzustellen, welche Optimierungen wirksam wurden. Beispielsweise möchten Sie möglicherweise überprüfen, ob GCC bei einigen rekursiven Funktionen eine Tail-Call-Optimierung durchführt, da Sie ohne diese Funktion möglicherweise den Stapel überlaufen können.
quelle
Ich bin überrascht, dass dies noch niemand gesagt hat - das für mich nützlichste Flag ist,
-g
dass Debugging-Informationen in die ausführbare Datei eingefügt werden, sodass Sie sie debuggen und durch die Quelle gehen können (es sei denn, Sie beherrschen und lesen Assembly und wie derstepi
Befehl) eines Programms, während es ausgeführt wird.quelle
-fmudflap - Fügt allen riskanten Zeigeroperationen Laufzeitprüfungen hinzu, um UB abzufangen . Dies immunisiert Ihr Programm effektiv gegen Pufferüberläufe und hilft, alle Arten von baumelnden Zeigern zu fangen.
Hier ist eine Demo:
quelle
-fmudflap
wird seit GCC 4.9 nicht mehr unterstütztwarning: switch '-fmudflap' is no longer supported
. Es wurde von AddressSanitizer ersetzt.Nicht wirklich mit C / C ++ verwandt, aber trotzdem nützlich:
Fügen Sie alle oben genannten guten Flags (die Sie alle angegeben haben) in eine 'Datei' ein und verwenden Sie dieses obige Flag, um alle Flags in dieser Datei zusammen zu verwenden.
z.B:
Datei: compilerFlags
Dann kompilieren Sie:
quelle
-march=native
um optimierten Code für die Plattform (= Chip) zu erstellen, auf der Sie kompilierenquelle
Wenn Sie die vom Compiler vordefinierten Präprozessor-Flags kennen müssen:
quelle
Es ist nicht wirklich hilfreich, um Fehler zu erkennen, aber die selten erwähnte
-masm=intel
Option macht die-S
Überprüfung der Baugruppenausgabe viel, viel schöner.Die Syntax der AT & T-Assembly schmerzt meinen Kopf viel zu sehr.
quelle
Mein Makefile enthält normalerweise
Die wichtigsten dieser Optionen wurden bereits erörtert, daher möchte ich auf die beiden Funktionen hinweisen, auf die noch nicht hingewiesen wurde:
Auch wenn ich auf einer Code - Basis gerade arbeite , dass Bedürfnisse Ebene C für die Portabilität zu einem gewissen Plattform sein , die noch keine anständigen C ++ Compiler hat, muß ich eine „extra“ Kompilierung mit dem C ++ Compiler (zusätzlich zu dem C - Compiler). Das hat 3 Vorteile:
Ja, ich bin eine hoffnungslos optimistische Pollyanna, die sicher jeden Monat daran denkt, dass eine Plattform entweder für veraltet erklärt wird oder einen anständigen C ++ - Compiler erhält, und wir können endlich zu C ++ wechseln. In meinen Augen ist das unvermeidlich - die einzige Frage ist, ob dies vor oder nach dem Management geschieht, das schließlich jedem ein Pony ausstellt. :-)
quelle
quelle
-Wold-style-definition
wenn Sie mit Rückfälligen zu tun haben, die Funktionen im K & R-Stil für eine gute Idee halten, selbst bei prototypisierten Deklarationen. (Ich muss mit solchen Leuten umgehen. Es ärgert mich wirklich, wenn ich neuen Code in K & R finde. Es ist schon schlimm genug, K & R-Legacy-Sachen zu haben, die nicht repariert sind, aber neuen Code! Grump !!!)Hier ist eine großartige Flagge, die nicht erwähnt wurde:
Geben Sie einen Fehler aus, wenn eine Funktion verwendet wird, bevor Sie deklariert werden.
quelle
Das Handbuch ist voller interessanter Flaggen mit guten Beschreibungen. -Wall wird gcc jedoch wahrscheinlich so ausführlich wie möglich machen. Wenn Sie interessantere Daten wünschen, sollten Sie sich valgrind oder ein anderes Tool ansehen, um nach Fehlern zu suchen.
quelle
man gcc | nl
meldet über 11000 Zeilen. Das ist mehr als die berüchtigtebash
Manpage!Nun,
-Wextra
sollte auch Standard sein.-Werror
verwandelt Warnungen in Fehler (was sehr ärgerlich sein kann, insbesondere wenn Sie ohne kompilieren-Wno-unused-result
).-pedantic
In Kombination mit erhaltenstd=c89
Sie zusätzliche Warnungen, wenn Sie C99-Funktionen verwenden.Aber das war es schon. Sie können einen C-Compiler nicht auf etwas typsparenderes als C selbst einstellen.
quelle
-M*
Familie von Optionen.Mit diesen können Sie make-Dateien schreiben, die automatisch herausfinden, von welchen Header-Dateien Ihre c- oder c ++ - Quelldateien abhängen sollten. GCC generiert Make-Dateien mit diesen Abhängigkeitsinformationen, und Sie schließen sie dann aus Ihrer primären Make-Datei ein.
Hier ist ein Beispiel für ein extrem generisches Makefile mit -MD und -MP, das ein Verzeichnis voller C ++ - Quell- und Header-Dateien kompiliert und alle Abhängigkeiten automatisch ermittelt:
Hier ist ein Blog-Beitrag, der es ausführlicher behandelt: http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html
quelle
Es gibt
-Werror
, das alle Warnungen als Fehler behandelt und die Kompilierung stoppt. Auf dergcc
Handbuchseite werden alle Befehlszeilenoptionen für Ihren Compiler erläutert.quelle
gcc
Flags zwischen Ihren und den von irgendjemandem vorgeschlagenen Links unterschiedlich sein. Aus diesem Grund werden Handbuchseiten mit Ihrer Software geliefert.-Wfloat-equal
Von: http://mces.blogspot.com/2005/07/char-const-argv.html
quelle
Ich habe festgestellt, dass dieser Thread nach einer Flagge sucht, um ein bestimmtes Problem zu beheben. Ich sehe sie hier nicht, daher füge ich eine hinzu, die mich in meinem Beitrag nur verblüfft hat :
Die
-Wformat=2
FlaggeUnd das wirklich Wichtige daran ( laut GCC-Handbuch ):
Nur weil Sie haben,
-Wall
heißt das nicht, dass Sie alles haben. ;)quelle
Ich benutze manchmal
-s
für eine viel kleinere ausführbare Datei:Quelle: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
quelle
strip
Ihre Binärdatei ausführen. Auf diese Weise können Sie eine Binärdatei mit Debug-Informationen erstellen und später zur Verteilung entfernen.strip
funktioniert auch,-s
kann aber schneller und einfacher sein, obwohl es nicht so aufwändig ist wie das Laufenstrip
Diese Antwort mag zwar etwas vom Thema abweichen und die Frage ist eine +1 von mir wert, da
Es gibt ein Tool, das ALLE Fehler und potenziellen Fehler aufspüren sollte, die möglicherweise nicht offensichtlich sind. Es gibt eine Schiene, mit der IMHO Fehler besser erkennen kann als mit gcc oder einem anderen Compiler. Das ist ein würdiges Werkzeug, das Sie in Ihrer Werkzeugkiste haben sollten.Die statische Überprüfung über ein fusselfreies Werkzeug wie eine Schiene sollte Teil einer Compiler-Toolchain sein.
quelle
Darüber hinaus ermöglicht
-Wall
die Option-W
oder-Wextra
(-W
funktioniert sowohl mit älteren als auch mit neueren Versionen von gcc; neuere Versionen unterstützen den alternativen Namen-Wextra
, was dasselbe bedeutet, aber aussagekräftiger ist) verschiedene zusätzliche Warnungen.Es gibt auch noch mehr Warnungen, die von keiner dieser Warnungen aktiviert werden, im Allgemeinen für Dinge, die fragwürdiger sind. Die Menge der verfügbaren Optionen ist abhängig davon , welche gcc Version Sie verwenden - konsultieren
man gcc
oderinfo gcc
für weitere Details oder die siehe Online - Dokumentation . Für die jeweilige gcc Version Sie interessiert sind und-pedantic
Probleme alle durch die jeweilige Norm bedarf Warnungen verwendet (das hängt auf andere Optionen wie-std=xxx
oder-ansi
) und beschwert sich über die Verwendung von gcc-Erweiterungen.-Werror
verwandelt alle Warnungen in Fehler. Ich glaube nicht, dass Sie mit gcc dies selektiv für bestimmte Warnungen tun können.Sie werden wahrscheinlich feststellen, dass Sie selektiv auswählen müssen, welche Warnungen pro Projekt aktiviert werden (insbesondere wenn Sie sie verwenden
-Werror
), da Header-Dateien aus externen Bibliotheken einige davon auslösen können. (-pedantic
Insbesondere ist dies meiner Erfahrung nach in dieser Hinsicht eher wenig hilfreich.)quelle
-Werror=some-warning
.-Wmissing-prototypes
: Wenn eine globale Funktion ohne vorherige Prototypdeklaration definiert ist.-Wformat-security
: Warnt vor der Verwendung von Formatfunktionen, die mögliche Sicherheitsprobleme darstellen. Derzeit warnt dies vor Aufrufenprintf
undscanf
Funktionen, bei denen die Formatzeichenfolge kein Zeichenfolgenliteral ist und keine Formatargumente vorhanden sindquelle
-Werror=return-type
: Fehler erzwingen, wenn die Funktion in gcc keine Rückgabe hat. Es ist/we4716
in Visual Studio.-Werror=implicit-function-declaration
: Fehler erzwingen, wenn die Funktion ohne definiert / nicht enthalten verwendet wird. Es ist/we4013
in Visual Studio.-Werror=incompatible-pointer-types
: Vor dem Fehler, wenn der Typ eines Zeigers nicht mit dem erwarteten Zeigertyp übereinstimmt. Es ist/we4133
in Visual Studio.Eigentlich möchte ich meinen C-Code plattformübergreifend behalten, CMake verwenden und die bereitgestellten cflags wie folgt in CMakeLists.txt einfügen:
quelle