Oft gcc
beginne ich in C unter mit den folgenden Warnflags (schmerzhaft aus mehreren Quellen zusammengestellt):
-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \
-Wfloat-equal -pedantic -ansi
Ich werde (zumindest meine Debug-Versionen) mit diesen Warnungen erstellen und alles reparieren, was ich kann (normalerweise alles), und dann nur Flags entfernen, wenn sie entweder nicht relevant oder nicht reparierbar sind (fast nie der Fall). Manchmal füge ich auch hinzu, -Werror
wenn ich beim Kompilieren zurücktreten muss.
Ich lerne gerade C ++ (ja, ich bin 15 Jahre hinter der Zeit zurück) und möchte auf dem richtigen Fuß beginnen.
Meine Frage ist: Hat jemand einen vorkompilierten ähnlichen Satz vollständiger Warnflags für C ++ unter g++
? (Ich weiß, dass viele von ihnen gleich sein werden.)
-Wall
) ist ein-Wbloody_everything
Flag :-)-Weverything
. Ich habe gelesen, dass selbst die Clang ++ - Entwickler ein wenig besorgt darüber sind, dass Benutzer es einschalten. anscheinend war es nur für den internen entwicklungsgebrauch gedacht. Das macht keinen Sinn, wenn auch, weil das Einschalten-Weverything
ist wahrscheinlich die beste Art und Weise möglicherweise hilfreich Warnungen zu entdecken , dass Sie nicht kennen , bevor.Antworten:
Ich ging durch und fand die minimale Anzahl von Includes, die die maximale Warnstufe erhalten sollten. Ich habe dann die Warnungen aus dieser Liste entfernt, die meiner Meinung nach nicht darauf hinweisen, dass etwas Schlimmes passiert, oder zu viele Fehlalarme haben, um in einem echten Build verwendet zu werden. Ich kommentierte, warum alle von mir ausgeschlossenen ausgeschlossen wurden. Dies ist meine letzte Reihe von vorgeschlagenen Warnungen:
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
Fragwürdige Warnungen, die vorhanden sind:
Ich füge hinzu,
-Wno-unused
weil ich oft Variablen habe, von denen ich weiß, dass ich sie später verwenden werde, aber noch nicht die Funktionalität habe, für die ich geschrieben habe. Durch das Entfernen von Warnungen kann ich in meinem bevorzugten Stil schreiben und gelegentlich die Implementierung von Dingen verschieben. Es ist nützlich, dies von Zeit zu Zeit auszuschalten, um sicherzustellen, dass nichts durch die Risse rutscht.-Wdisabled-optimization
scheint eine starke Benutzereinstellung zu sein. Ich habe dieses gerade zu meinem Build hinzugefügt (nur für optimierte Builds aus offensichtlichen Gründen) und es hat nichts ergeben, daher scheint es keine besonders gesprächige Warnung zu sein, zumindest für die Art und Weise, wie ich codiere. Ich füge es hinzu (obwohl Code, der diese Warnung auslöst, nicht unbedingt falsch ist), weil ich daran glaube, mit meinen Tools zu arbeiten, anstatt gegen sie. Wenn gcc mir sagt, dass es den Code nicht für die Art und Weise optimieren kann, wie ich ihn geschrieben habe, sollte ich versuchen, ihn neu zu schreiben. Ich vermute, dass Code, der diese Warnung auslöst, davon profitieren könnte, unabhängig davon modularer zu sein. Obwohl der Code (wahrscheinlich) technisch nicht falsch ist, ist er es stilistisch wahrscheinlich.-Wfloat-equal
warnt vor sicheren Gleichheitsvergleichen (insbesondere Vergleich mit einem nicht berechneten Wert von -1). Ein Beispiel in meinem Code, in dem ich dies verwende, ist, dass ich einen Float-Vektor habe. Ich gehe diesen Vektor durch und es gibt einige Elemente, die ich noch nicht bewerten kann, was sie sein sollten. Deshalb setze ich sie auf -1,0f (da mein Problem nur positive Zahlen verwendet, liegt -1 außerhalb der Domäne). Ich gehe später durch und aktualisiere -1.0f Werte. Es eignet sich nicht leicht für eine andere Arbeitsweise. Ich vermute, dass die meisten Leute dieses Problem nicht haben, und der Vergleich einer exakten Zahl im Gleitkomma ist wahrscheinlich ein Fehler, deshalb nehme ich ihn in die Standardliste auf.-Wold-style-cast
Der von mir verwendete Bibliothekscode enthält viele Fehlalarme. Insbesondere die im Netzwerk verwendete htonl-Funktionsfamilie sowie eine von mir verwendete Rijndael (AES) -Verschlüsselungsimplementierung weisen Casts im alten Stil auf, vor denen ich gewarnt werde. Ich beabsichtige, beide zu ersetzen, bin mir aber nicht sicher, ob mein Code noch etwas enthält, über das er sich beschweren wird. Die meisten Benutzer sollten dies jedoch wahrscheinlich standardmäßig aktiviert haben.-Wsign-conversion
war eine schwierige Frage (und hätte es fast nicht auf die Liste geschafft). Das Aktivieren in meinem Code erzeugte eine große Anzahl von Warnungen (100+). Fast alle von ihnen waren unschuldig. Ich habe jedoch darauf geachtet, vorzeichenbehaftete Ganzzahlen zu verwenden, wo immer ich nicht sicher war, obwohl ich für meine spezielle Problemdomäne aufgrund der großen Anzahl von Ganzzahldivisionen, die ich mache, normalerweise eine leichte Effizienzsteigerung mit vorzeichenlosen Werten erzielen würde. Ich habe diese Effizienz geopfert, weil ich besorgt war, versehentlich eine vorzeichenbehaftete Ganzzahl in eine vorzeichenlose Ganzzahl umzuwandeln und dann zu teilen (was im Gegensatz zu Addition, Subtraktion und Multiplikation nicht sicher ist). Durch Aktivieren dieser Warnung konnte ich die meisten meiner Variablen sicher in vorzeichenlose Typen ändern und an einigen anderen Stellen einige Casts hinzufügen. Es ist derzeit etwas schwierig zu verwenden, da die Warnung nicht so intelligent ist. Zum Beispiel, wenn Sie dies tununsigned short + (integral constant expression)
wird dieses Ergebnis implizit zu int befördert. Es warnt dann vor einem möglichen Vorzeichenproblem, wenn Sie diesen Wertunsigned
oder zuweisen,unsigned short
obwohl er sicher ist. Dies ist definitiv die optionalste Warnung für fast alle Benutzer.-Wsign-promo
: sehen-Wsign-conversion
.-Wswitch-default
scheint sinnlos (Sie möchten nicht immer einen Standardfall, wenn Sie alle Möglichkeiten explizit aufgezählt haben). Das Aktivieren dieser Warnung kann jedoch etwas erzwingen, das wahrscheinlich eine gute Idee ist. In Fällen, in denen Sie explizit alles außer den aufgeführten Möglichkeiten ignorieren möchten (aber andere Zahlen sind möglich), geben Sie eindefault: break;
um es explizit zu machen. Wenn Sie alle Möglichkeiten explizit auflisten, können Sie durch Aktivieren dieser Warnung sicherstellen, dass Sie so etwas wie assert (false) eingeben, um sicherzustellen, dass Sie tatsächlich alle möglichen Optionen abgedeckt haben. Sie können damit explizit angeben, in welcher Domäne sich Ihr Problem befindet, und dies programmgesteuert durchsetzen. Sie müssen jedoch vorsichtig sein, wenn Sie die Behauptung (falsch) überall festhalten. Es ist besser, als mit dem Standardfall nichts zu tun, aber wie bei Assert üblich, funktioniert es in Release-Builds nicht. Mit anderen Worten, Sie können sich nicht darauf verlassen, dass Sie Nummern validieren, die Sie beispielsweise von einer Netzwerkverbindung oder einer Datenbank erhalten, über die Sie keine absolute Kontrolle haben. Ausnahmen oder frühzeitige Rückkehr sind der beste Weg, um damit umzugehen (aber Sie müssen immer noch einen Standardfall haben!).-Werror
ist wichtig für mich. Wenn Sie große Codemengen in einem Multithread-Build mit mehreren Zielen kompilieren, kann eine Warnung leicht übersehen werden. Das Verwandeln von Warnungen in Fehler stellt sicher, dass ich sie bemerke.Dann gibt es eine Reihe von Warnungen, die nicht in der obigen Liste enthalten sind, weil ich sie nicht als nützlich empfunden habe. Dies sind die Warnungen und meine Kommentare dazu, warum ich sie nicht in die Standardliste aufnehme:
Warnungen fehlen:
-Wabi
wird nicht benötigt, da ich keine Binärdateien von verschiedenen Compilern kombiniere. Ich habe trotzdem versucht, damit zu kompilieren, und es hat nicht ausgelöst, so dass es nicht unnötig ausführlich erscheint.-Waggregate-return
ist nicht etwas, das ich als Fehler betrachte. Beispielsweise wird es ausgelöst, wenn eine bereichsbasierte for-Schleife für einen Klassenvektor verwendet wird. Die Rückgabewertoptimierung sollte negative Auswirkungen berücksichtigen.-Wconversion
Auslöser für diesen Code:short n = 0; n += 2;
Die implizite Konvertierung in int verursacht eine Warnung, wenn sie dann wieder in ihren Zieltyp konvertiert wird.-Weffc++
enthält eine Warnung, wenn nicht alle Datenelemente in der Initialisierungsliste initialisiert sind. Ich mache dies in vielen Fällen absichtlich nicht, daher sind die Warnungen zu überladen, um nützlich zu sein. Es ist jedoch hilfreich, ab und zu einzuschalten und nach anderen Warnungen zu suchen (z. B. nicht virtuelle Destruktoren von Basisklassen). Dies wäre nützlicher als eine Sammlung von Warnungen (wie-Wall
) anstelle einer einzelnen Warnung für sich.-Winline
fehlt, weil ich das Inline-Schlüsselwort nicht zu Optimierungszwecken verwende, nur um Funktionen in Headern inline zu definieren. Es ist mir egal, ob der Optimierer es tatsächlich inline. Diese Warnung beschwert sich auch, wenn eine in einem Klassenkörper deklarierte Funktion (z. B. ein leerer virtueller Destruktor) nicht integriert werden kann.-Winvalid-pch
fehlt, weil ich keine vorkompilierten Header verwende.-Wmissing-format-attribute
wird nicht verwendet, da ich keine Gnu-Erweiterungen verwende. Gleiches für-Wsuggest-attribute
und mehrere andereMöglicherweise bemerkenswert für seine Abwesenheit ist
-Wno-long-long
, was ich nicht brauche. Ich kompiliere mit-std=c++0x
(-std=c++11
in GCC 4.7), daslong long
ganzzahlige Typen enthält. Diejenigen, die auf C ++ 98 / C ++ 03 zurückbleiben, können diesen Ausschluss aus der Warnliste hinzufügen.-Wnormalized=nfc
ist bereits die Standardoption und scheint die beste zu sein.-Wpadded
wird gelegentlich aktiviert, um das Layout von Klassen zu optimieren, wird jedoch nicht aktiviert, da nicht alle Klassen über genügend Elemente verfügen, um das Auffüllen am Ende zu entfernen. Theoretisch könnte ich einige zusätzliche Variablen kostenlos erhalten, aber es lohnt sich nicht, diese beizubehalten (wenn sich meine Klassengröße ändert, ist es nicht einfach, diese zuvor freien Variablen zu entfernen).-Wstack-protector
wird nicht verwendet, weil ich nicht benutze-fstack-protector
-Wstrict-aliasing=3
wird von eingeschaltet-Wall
und ist am genauesten, aber es sieht so aus, als würden Level 1 und 2 mehr Warnungen geben. Theoretisch ist eine niedrigere Stufe eine "stärkere" Warnung, geht jedoch zu Lasten von mehr Fehlalarmen. Mein eigener Testcode wurde unter allen 3 Ebenen sauber kompiliert.-Wswitch-enum
ist kein Verhalten, das ich will. Ich möchte nicht jede switch-Anweisung explizit behandeln. Es wäre nützlich, wenn die Sprache einen Mechanismus hätte, um dies für bestimmte switch-Anweisungen zu aktivieren (um sicherzustellen, dass zukünftige Änderungen an der Aufzählung überall dort behandelt werden, wo sie benötigt werden), aber es ist übertrieben für eine "Alles-oder-Nichts" -Einstellung.-Wunsafe-loop-optimizations
verursacht zu viele falsche Warnungen. Es kann nützlich sein, diese regelmäßig anzuwenden und die Ergebnisse manuell zu überprüfen. Als Beispiel wurde diese Warnung in meinem Code generiert, als ich alle Elemente in einem Vektor durchlaufen habe, um eine Reihe von Funktionen auf sie anzuwenden (unter Verwendung der bereichsbasierten for-Schleife). Es ist auch eine Warnung für den Konstruktor eines const-Arrays von const std :: string (wobei dies keine Schleife im Benutzercode ist).-Wzero-as-null-pointer-constant
und-Wuseless-cast
sind nur GCC-4.7-Warnungen, die ich beim Übergang zu GCC 4.7 hinzufügen werde.Ich habe aufgrund einiger dieser Untersuchungen einige Fehlerberichte / Erweiterungsanfragen bei gcc eingereicht, sodass ich hoffentlich in der Lage sein werde, eventuell weitere Warnungen aus der Liste "Nicht einschließen" in die Liste "Einschließen" aufzunehmen . Diese Liste enthält alle in diesem Thread erwähnten Warnungen (und ich denke ein paar zusätzliche). Viele der Warnungen, die in diesem Beitrag nicht ausdrücklich erwähnt werden, sind Teil einer anderen Warnung, die ich erwähne. Wenn jemand Warnungen bemerkt, die von diesem Beitrag vollständig ausgeschlossen sind, lass es mich wissen.
edit: Es sieht so aus, als hätte ich mehrere verpasst (die ich jetzt hinzugefügt habe). Es gibt tatsächlich eine zweite Seite unter http://gcc.gnu.org , die ziemlich gut versteckt ist. Allgemeine Warnoptionen und C ++ - Optionen (für Warnungen nach unten scrollen)
quelle
-Wswitch-enum
warnt, wenn Sie nicht jeden Aufzählungswert in einem Switch explizit behandeln unddefault
nicht als explizit gelten.-Wswitch-default
Warnt Sie andererseits, wenn Ihr Switch keinendefault
Fall hat, auch wenn Sie alle möglichen Werte explizit abgedeckt haben.-isystem
anstelle-I
Ihres "alten Bibliothekscodes", um all diese Fehlalarme zu verhindernD'oh, alle meine ursprünglichen Suchanfragen ergaben 99% der Beiträge zum Unterdrücken von Warnungen (beängstigend genug), aber ich bin gerade auf diesen Kommentar gestoßen , der diese schönen Flaggen enthält (einige weniger relevant):
Gegenübergestellt mit:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Ich denke, das ist ein guter Ausgangspunkt. Ich wusste nicht, dass dies ein Betrug war, aber zumindest war es tief begraben. :-)
quelle
-Wall
es nicht das tut, was man erwarten würde. Aber danke, einige davon sehen sehr nützlich aus!-Waggregate-return
? Dies gibt mir eine Warnung für jede Verwendung vonbegin/end()
Einige davon sind bereits in
-Wall
oder enthalten-Wextra
.Ein gutes Basis-Setup für C ist:
-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror
und für C ++
-ansi -pedantic -Wall -Wextra -Weffc++
(Überspringen
-Werror
für C ++ hat da-Weffc++
einige Ärger)quelle
-std=c89
. Im C ++ - Modus entspricht dies-std=c++98
. dh wenn Sie eine andere angebenstd
, verwenden Sie nichtansi
Versuchen
Das ist ein schneller und schmutziger Start, der definitiv etwas verbessert werden muss. Selbst wenn Sie den Compiler mit dem für Ihre Sprache geeigneten Namen aufrufen (z. B.
g++
für C ++), erhalten Sie Warnungen, die für diese Sprache nicht gelten (und der Compiler erhebt die Hände und weigert sich, bis Sie fortzufahren entfernen Sie die Warnung).Eine andere Sache ist, dass ich hinzugefügt habe
-Werror
, denn wenn Sie die Warnungen nicht korrigieren, warum ist es Ihnen wichtig, sie einzuschalten? Sie können auch Warnungen aus der Liste entfernen. (Zum Beispiel verwende ich fast nie-Waggregate-return
mit C ++.)Einige Warnungen werden ohne andere leistungsbezogene Optionen (
-Wstack-protector
) nichts bewirken .-fdiagnostics-show-option
und das GCC-Handbuch sind deine Freunde.Übrigens schließen sich einige Warnungen gegenseitig aus. insbesondere mit
-Wtraditional
und-Wold-style-definition
zusammen mit-Werror
wird nicht kompiliert.quelle
In der CmakeLists.txt meines Clion
quelle