Warum Warnungen aktivieren?
C- und C ++ - Compiler sind bekanntermaßen schlecht darin, einige häufige Programmiererfehler standardmäßig zu melden , wie z.
- Vergessen, eine Variable zu initialisieren
- Vergessen
return
eines Wertes aus einer Funktion
- Argumente in
printf
und scanf
Familien, die nicht mit der Formatzeichenfolge übereinstimmen
- Eine Funktion wird verwendet, ohne vorher deklariert zu werden (nur C).
Diese können erkannt und gemeldet werden, normalerweise jedoch nicht standardmäßig. Diese Funktion muss explizit über Compileroptionen angefordert werden.
Wie aktiviere ich Warnungen?
Dies hängt von Ihrem Compiler ab.
Microsoft C und C ++ Compiler verstehen Schalter wie /W1
, /W2
, /W3
, /W4
und /Wall
. Verwenden Sie mindestens /W3
. /W4
und /Wall
kann falsche Warnungen für Systemheaderdateien ausgeben, aber wenn Ihr Projekt mit einer dieser Optionen sauber kompiliert wird, versuchen Sie es. Diese Optionen schließen sich gegenseitig aus.
Die meisten anderen Compilern verstehen Optionen wie -Wall
, -Wpedantic
und -Wextra
. -Wall
ist wichtig und alle anderen werden empfohlen (beachten Sie, dass trotz des Namens -Wall
nur die wichtigsten Warnungen aktiviert werden, nicht alle ). Diese Optionen können einzeln oder alle zusammen verwendet werden.
Ihre IDE kann diese möglicherweise über die Benutzeroberfläche aktivieren.
Warum Warnungen als Fehler behandeln? Sie sind nur Warnungen!
Eine Compiler-Warnung weist auf ein möglicherweise schwerwiegendes Problem in Ihrem Code hin. Die oben aufgeführten Probleme sind fast immer tödlich. andere können es sein oder auch nicht, aber Sie möchten, dass die Kompilierung fehlschlägt, auch wenn sich herausstellt, dass es sich um einen Fehlalarm handelt. Untersuchen Sie jede Warnung, finden Sie die Grundursache und beheben Sie sie. Umgehen Sie im Falle eines Fehlalarms das Problem, indem Sie eine andere Sprachfunktion oder ein anderes Konstrukt verwenden, damit die Warnung nicht mehr ausgelöst wird. Wenn sich dies als sehr schwierig herausstellt, deaktivieren Sie diese bestimmte Warnung von Fall zu Fall.
Sie möchten Warnungen nicht einfach als Warnungen belassen, auch wenn es sich bei allen um Fehlalarme handelt. Es könnte für sehr kleine Projekte in Ordnung sein, bei denen die Gesamtzahl der ausgegebenen Warnungen weniger als 7 beträgt. Alles andere und es ist leicht, dass eine neue Warnung in einer Flut von alten vertrauten Warnungen verloren geht. Erlaube das nicht. Lassen Sie einfach Ihr gesamtes Projekt sauber kompilieren.
Beachten Sie, dass dies für die Programmentwicklung gilt. Wenn Sie Ihr Projekt in der Quellform für die Welt freigeben, ist es möglicherweise eine gute Idee, -Werror
Ihr veröffentlichtes Build-Skript nicht oder nicht gleichwertig bereitzustellen. Möglicherweise wird versucht, Ihr Projekt mit einer anderen Version des Compilers oder mit einem anderen Compiler zu erstellen, für den möglicherweise andere Warnungen aktiviert sind. Möglicherweise möchten Sie, dass ihr Build erfolgreich ist. Es ist immer noch eine gute Idee, die Warnungen aktiviert zu lassen, damit Personen, die Warnmeldungen sehen, Ihnen Fehlerberichte oder Patches senden können.
Wie werden Warnungen als Fehler behandelt?
Dies geschieht wiederum mit Compiler-Switches. /WX
ist für Microsoft, die meisten anderen verwenden -Werror
. In beiden Fällen schlägt die Kompilierung fehl, wenn Warnungen ausgegeben werden.
C ist bekanntlich eine eher einfache Sprache, wenn es um HLLs geht. C ++ scheint zwar eine wesentlich höhere Sprache als C zu sein, weist jedoch einige seiner Merkmale auf. Und eines dieser Merkmale ist, dass die Sprachen von Programmierern für Programmierer entwickelt wurden - und insbesondere von Programmierern, die wussten, was sie taten.
[Für den Rest dieser Antwort werde ich mich auf C konzentrieren. Das meiste, was ich sagen werde, gilt auch für C ++, wenn auch vielleicht nicht so stark. Obwohl, wie Bjarne Stroustrup berühmt gesagt hat: "C macht es einfach, sich in den Fuß zu schießen; C ++ macht es schwieriger, aber wenn Sie es tun, bläst es Ihr ganzes Bein ab." ]]
Wenn Sie wissen, was Sie tun - wirklich wissen, was Sie tun - müssen Sie manchmal "die Regeln brechen". Aber die meiste Zeit werden die meisten von uns zustimmen, dass gut gemeinte Regeln uns alle aus Ärger heraushalten und dass es eine schlechte Idee ist, diese Regeln ständig zu brechen.
Aber in C und C ++ gibt es überraschend viele Dinge, die Sie tun können, die "schlechte Ideen" sind, die aber formal nicht "gegen die Regeln" sind. Manchmal sind sie manchmal eine schlechte Idee (aber manchmal können sie verteidigt werden); Manchmal sind sie fast immer eine schlechte Idee. Aber die Tradition war immer, nicht vor diesen Dingen zu warnen - denn wiederum wird davon ausgegangen, dass Programmierer wissen, was sie tun, sie würden diese Dinge nicht ohne guten Grund tun, sie würden sich über einen Haufen ärgern von unnötigen Warnungen.
Aber natürlich wissen nicht alle Programmierer wirklich , was sie tun. Insbesondere durchläuft jeder C-Programmierer (egal wie erfahren) eine Phase, in der er ein beginnender C-Programmierer ist. Und selbst erfahrene C-Programmierer können nachlässig werden und Fehler machen.
Schließlich hat die Erfahrung nicht nur gezeigt, dass Programmierer Fehler machen, sondern dass diese Fehler echte, schwerwiegende Folgen haben können. Wenn Sie einen Fehler machen und der Compiler Sie nicht davor warnt und das Programm nicht sofort abstürzt oder etwas offensichtlich Falsches tut, kann der Fehler dort lauern, manchmal jahrelang versteckt, bis er verursacht ein wirklich großes Problem.
Es stellt sich also heraus, dass Warnungen meistens eine gute Idee sind. Sogar die erfahrenen Programmierer haben gelernt (tatsächlich haben " besonders die erfahrenen Programmierer gelernt"), dass die Warnungen insgesamt mehr Gutes als Schaden anrichten. Für jedes Mal, wenn Sie absichtlich etwas falsch gemacht haben und die Warnung ein Ärgernis war, haben Sie wahrscheinlich mindestens zehn Mal versehentlich etwas falsch gemacht, und die Warnung hat Sie vor weiteren Problemen bewahrt. Und die meisten Warnungen können für die wenigen Male deaktiviert oder umgangen werden, wenn Sie wirklich das "Falsche" tun möchten.
(Ein klassisches Beispiel für eine solche „Fehler“ ist der Test Die
if(a = b)
meiste Zeit, ist dies ein Fehler ist, so dass die meisten Compiler in diesen Tagen darüber warnen -.. Einige sogar standardmäßig Aber wenn Sie wirklich sowohl assign wollteb
zua
und Test Im Ergebnis können Sie die Warnung durch Eingabe deaktivierenif((a = b))
.)Die zweite Frage ist, warum Sie den Compiler bitten möchten, Warnungen als Fehler zu behandeln. Ich würde sagen, es liegt an der menschlichen Natur, insbesondere an der allzu einfachen Reaktion, zu sagen: "Oh, das ist nur eine Warnung, das ist nicht so wichtig, ich werde das später aufräumen." Aber wenn Sie ein Zauderer sind (und ich weiß nichts über Sie, aber ich bin ein schrecklicher Zauderer), ist es einfach, die notwendige Bereinigung für immer zu verschieben - und wenn Sie es sich zur Gewohnheit machen, Warnungen zu ignorieren, dann Es wird immer einfacher, eine wichtige Warnmeldung zu übersehen , die unbemerkt inmitten all derer liegt, die Sie ignorieren.
Den Compiler zu bitten, Warnungen als Fehler zu behandeln, ist ein kleiner Trick, den Sie selbst spielen können, um diese menschliche Schwäche zu umgehen.
Persönlich bestehe ich nicht so darauf, Warnungen als Fehler zu behandeln. (In der Tat, wenn ich ehrlich bin, kann ich sagen, dass ich diese Option in meiner "persönlichen" Programmierung praktisch nie aktiviere.) Aber Sie können sicher sein, dass ich diese Option bei der Arbeit aktiviert habe, wo unser Styleguide (den ich schrieb) beauftragt seine Verwendung. Und ich würde sagen - ich vermute, die meisten professionellen Programmierer würden sagen -, dass jeder Shop, der Warnungen nicht als Fehler in C behandelt, sich verantwortungslos verhält und sich nicht an allgemein anerkannte Best Practices der Branche hält.
quelle
if(a = b)
, daher müssen wir nicht davor warnen." (Dann erstellt jemand eine Liste von 10 kritischen Fehlern in 10 veröffentlichten Produkten, die aus diesem speziellen Fehler resultieren.) "Okay, kein erfahrener C-Programmierer würde das jemals schreiben ..."if (returnCodeFromFoo = foo(bar))
und meinen, um den Code an einem Ort zu erfassen und zu testen (Angenommen, der einzige Zweckfoo
besteht darin, Nebenwirkungen zu haben!). Die Tatsache, dass ein wirklich wirklich erfahrener Programmierer weiß, dass dies kein Problem ist Guter Codierungsstil istif (returnCodeFromFoo = foo(bar))
, geben sie einen Kommentar ein und deaktivieren die Warnung (sodass der Wartungsprogrammierer 4 Jahre später erkennt, dass der Code beabsichtigt ist. Das heißt, ich habe gearbeitet mit jemandem, der in (in Microsoft C ++) darauf bestand, dass das Kombinieren von / Wall mit dem Behandeln von Warnungen als Fehler derWarnungen bestehen aus den besten Ratschlägen, die einige der erfahrensten C ++ - Entwickler in eine Anwendung einbinden könnten. Sie sind es wert, hier zu bleiben.
C ++ ist eine vollständige Turing-Sprache und hat viele Fälle, in denen der Compiler einfach darauf vertrauen muss, dass Sie wissen, was Sie tun. Es gibt jedoch viele Fälle, in denen der Compiler erkennen kann, dass Sie wahrscheinlich nicht beabsichtigten, das zu schreiben, was Sie geschrieben haben. Ein klassisches Beispiel sind printf () - Codes, die nicht mit den Argumenten übereinstimmen, oder an printf übergebene std :: strings (nicht, dass mir das jemals passiert!). In diesen Fällen ist der von Ihnen geschriebene Code kein Fehler. Es ist ein gültiger C ++ - Ausdruck mit einer gültigen Interpretation, auf die der Compiler reagieren kann. Der Compiler hat jedoch die starke Vermutung, dass Sie einfach etwas übersehen haben, das für einen modernen Compiler leicht zu erkennen ist. Dies sind Warnungen. Dies sind Dinge, die für einen Compiler offensichtlich sind, wenn er alle strengen Regeln von C ++ verwendet, die Sie möglicherweise übersehen haben.
Das Deaktivieren oder Ignorieren von Warnungen ist wie das Ignorieren von kostenlosen Ratschlägen von Fachleuten als Ihnen. Es ist eine Lektion in Huberis, die entweder endet, wenn Sie zu nahe an der Sonne fliegen und Ihre Flügel schmelzen, oder wenn ein Speicherfehler auftritt. Zwischen den beiden werde ich jeden Tag vom Himmel fallen!
"Warnungen als Fehler behandeln" ist die extreme Version dieser Philosophie. Die Idee dabei ist, dass Sie jede Warnung des Compilers auflösen - Sie hören sich jeden kostenlosen Rat an und handeln danach. Ob dies ein gutes Entwicklungsmodell für Sie ist, hängt vom Team und der Art des Produkts ab, an dem Sie arbeiten. Es ist der asketische Ansatz, den ein Mönch haben könnte. Für einige funktioniert es großartig. Für andere nicht.
In vielen meiner Anwendungen behandeln wir Warnungen nicht als Fehler. Wir tun dies, weil diese speziellen Anwendungen auf mehreren Plattformen mit mehreren Compilern unterschiedlichen Alters kompiliert werden müssen. Manchmal stellen wir fest, dass es tatsächlich unmöglich ist, eine Warnung auf einer Seite zu korrigieren, ohne dass daraus eine Warnung auf einer anderen Plattform wird. Wir sind also nur vorsichtig. Wir respektieren Warnungen, aber wir beugen uns für sie nicht nach hinten.
quelle
equals
/ zu schreibenhashCode
), und es handelt sich um ein Problem mit der Qualität der Implementierung, über das berichtet wird.Der Umgang mit den Warnungen macht nicht nur den Code besser, sondern macht Sie auch zu einem besseren Programmierer. Warnungen werden Sie über Dinge informieren, die Ihnen heute vielleicht wenig erscheinen, aber eines Tages wird diese schlechte Angewohnheit zurückkommen und Ihnen den Kopf abbeißen.
Verwenden Sie den richtigen Typ, geben Sie diesen Wert zurück und bewerten Sie diesen Rückgabewert. Nehmen Sie sich Zeit und überlegen Sie: "Ist das in diesem Zusammenhang wirklich der richtige Typ?" "Muss ich das zurückgeben?" Und der Biggie; "Wird dieser Code in den nächsten 10 Jahren portabel sein?"
Gewöhnen Sie sich an, in erster Linie warnfreien Code zu schreiben.
quelle
Die anderen Antworten sind ausgezeichnet und ich möchte nicht wiederholen, was sie gesagt haben.
Ein weiterer Aspekt von "Warum Warnungen aktivieren", der nicht richtig angesprochen wurde, ist, dass sie bei der Codepflege enorm helfen. Wenn Sie ein Programm von beträchtlicher Größe schreiben, wird es unmöglich, das Ganze auf einmal im Kopf zu behalten. Normalerweise haben Sie eine oder drei Funktionen, über die Sie aktiv schreiben und nachdenken, und möglicherweise eine oder drei Dateien auf Ihrem Bildschirm, auf die Sie verweisen können, aber der Großteil des Programms befindet sich irgendwo im Hintergrund, und Sie müssen darauf vertrauen arbeitet weiter.
Wenn Sie Warnungen aktiviert haben und diese so energisch und in Ihrem Gesicht wie möglich haben, können Sie benachrichtigt werden, wenn etwas, das Sie ändern, Probleme mit etwas verursacht, das Sie nicht sehen können.
Nehmen Sie zum Beispiel die Klirrwarnung
-Wswitch-enum
. Dies löst eine Warnung aus, wenn Sie einen Schalter für eine Aufzählung verwenden und einen der möglichen Aufzählungswerte verpassen. Es ist etwas, von dem Sie vielleicht denken, dass es ein unwahrscheinlicher Fehler ist: Sie haben sich wahrscheinlich zumindest die Liste der Enum-Werte angesehen, als Sie die switch-Anweisung geschrieben haben. Möglicherweise haben Sie sogar eine IDE, die die Switch-Optionen für Sie generiert hat und keinen Raum für menschliches Versagen lässt.Diese Warnung kommt wirklich zur Geltung, wenn Sie sechs Monate später einen weiteren möglichen Eintrag in die Aufzählung aufnehmen. Wenn Sie über den fraglichen Code nachdenken, wird es Ihnen wahrscheinlich gut gehen. Wenn diese Aufzählung jedoch für mehrere verschiedene Zwecke verwendet wird und für einen der Zwecke, für die Sie die zusätzliche Option benötigen, können Sie leicht vergessen, einen Schalter in einer Datei zu aktualisieren, die Sie seit 6 Monaten nicht mehr berührt haben.
Sie können sich Warnungen genauso vorstellen wie automatisierte Testfälle: Sie helfen Ihnen, sicherzustellen, dass der Code sinnvoll ist und tun, was Sie beim ersten Schreiben benötigen, aber sie helfen noch mehr, dies sicherzustellen macht weiter, was du brauchst, während du daran stößt. Der Unterschied besteht darin, dass Testfälle sehr eng an den Anforderungen Ihres Codes arbeiten und Sie diese schreiben müssen, während Warnungen für fast den gesamten Code weitgehend nach vernünftigen Standards funktionieren und von den Boffins, die die Compiler erstellen, sehr großzügig bereitgestellt werden.
quelle
Nicht festgelegte Warnungen führen früher oder später zu Fehlern in Ihrem Code .
Zum Debuggen eines Segmentierungsfehlers muss der Programmierer beispielsweise die Ursache des Fehlers verfolgen, die sich normalerweise an einer früheren Stelle in Ihrem Code befindet als die Zeile, die schließlich den Segmentierungsfehler verursacht hat.
Es ist sehr typisch, dass die Ursache eine Zeile ist, für die der Compiler eine Warnung ausgegeben hat, die Sie ignoriert haben, und die Zeile, die den Segmentierungsfehler verursacht hat, die Zeile, die schließlich den Fehler ausgelöst hat.
Das Beheben der Warnung führt zum Beheben des Problems. Ein Klassiker!
Eine Demonstration des oben genannten. Betrachten Sie den folgenden Code:
was beim Kompilieren mit dem an GCC übergebenen "Wextra" -Flag ergibt:
was ich sowieso ignorieren und den Code ausführen könnte . Und dann würde ich einen "großen" Segmentierungsfehler erleben, wie mein IP-Epicurus-Professor sagte:
Um dies in einem realen Szenario zu debuggen, würde man von der Zeile ausgehen, die den Segmentierungsfehler verursacht, und versuchen, die Ursache der Ursache zu ermitteln. Sie müssten nach dem suchen, was mit
i
undstr
innerhalb dieser kolossalen Menge geschehen ist von Code dort drüben ...Bis sie sich eines Tages in der Situation befanden, in der sie entdeckten, dass
idx
sie nicht initialisiert verwendet wird, hat sie einen Müllwert , der dazu führt, dass die Zeichenfolge (weit) außerhalb ihrer Grenzen indiziert wird, was zu einem Segmentierungsfehler führt.Wenn sie die Warnung nur nicht ignoriert hätten, hätten sie den Fehler sofort gefunden!
quelle
str[idx]
“ ist nicht „Okay, wo sindstr
undidx
definiert`?idx
den Wert, den Sie für Ihren Test erwartet haben (nicht zu unwahrscheinlich, wenn der erwartete Wert 0 ist), und verweisen tatsächlich auf einige vertrauliche Daten, die bei der Bereitstellung niemals gedruckt werden sollten.Warnungen als Fehler zu behandeln ist nur ein Mittel der Selbstdisziplin: Sie haben ein Programm kompiliert, um diese glänzende neue Funktion zu testen, aber Sie können es nicht, bis Sie die schlampigen Teile repariert haben. Es gibt keine zusätzlichen Informationen
Werror
, sondern nur sehr klare Prioritäten:Es ist wirklich die Denkweise, die wichtig ist, nicht die Werkzeuge. Die Compiler-Diagnoseausgabe ist ein Werkzeug. MISRA (für Embedded C) ist ein weiteres Tool. Es spielt keine Rolle, welches Sie verwenden, aber Compiler-Warnungen sind wohl das einfachste Tool, das Sie erhalten können (es ist nur ein Flag zum Setzen), und das Signal-Rausch-Verhältnis ist sehr hoch. Es gibt also keinen Grund, es nicht zu benutzen.
Kein Werkzeug ist unfehlbar. Wenn Sie schreiben
const float pi = 3.14;
, sagen Ihnen die meisten Tools nicht, dass Sie π mit einer schlechten Genauigkeit definiert haben, was später zu Problemen führen kann. Die meisten Tools ziehen keine Augenbrauen hochif(tmp < 42)
, auch wenn allgemein bekannt ist, dass die Angabe von bedeutungslosen Namen für Variablen und die Verwendung magischer Zahlen eine Möglichkeit ist, in großen Projekten eine Katastrophe zu verursachen. Sie müssen verstehen, dass jeder "Schnelltest" -Code, den Sie schreiben, genau das ist: ein Test, und Sie müssen ihn richtig machen, bevor Sie mit anderen Aufgaben fortfahren, während Sie immer noch seine Mängel sehen. Wenn Sie diesen Code unverändert lassen, wird das Debuggen erheblich schwieriger, wenn Sie nach zwei Monaten neue Funktionen hinzufügen.Sobald Sie die richtige Einstellung gefunden haben, macht es keinen Sinn, sie zu verwenden
Werror
. Wenn Sie Warnungen als Warnungen haben, können Sie eine fundierte Entscheidung treffen, ob es noch sinnvoll ist, die Debug-Sitzung auszuführen, die Sie gerade starten wollten, oder sie abzubrechen und die Warnungen zuerst zu beheben.quelle
clippy
warnt das Flusenwerkzeug für Rust tatsächlich vor der Konstante "3.14". Es ist eigentlich ein Beispiel in den Dokumenten . Aber wie Sie vielleicht aus dem Namen erraten können, ist erclippy
stolz darauf, aggressiv hilfreich zu sein.Als jemand, der mit altem eingebettetem C-Code arbeitet, hat das Aktivieren von Compiler-Warnungen dazu beigetragen, viele Schwachstellen und Bereiche aufzuzeigen, die untersucht werden müssen, wenn Korrekturen vorgeschlagen werden. In gcc nutzen
-Wall
und-Wextra
und sind sogar-Wshadow
lebenswichtig geworden. Ich werde nicht jede einzelne Gefahr angehen, aber ich werde einige auflisten, die aufgetaucht sind und dazu beigetragen haben, Codeprobleme aufzuzeigen.Variablen bleiben zurück
Dieser kann leicht auf unvollendete Arbeiten und Bereiche verweisen, in denen möglicherweise nicht alle übergebenen Variablen verwendet werden, was ein Problem sein könnte. Schauen wir uns eine einfache Funktion an, die dies auslösen kann:
Nur das Kompilieren ohne -Wall oder -Wextra gibt keine Probleme zurück. -Wand wird Ihnen sagen, obwohl das
c
nie verwendet wird:-Wextra sagt Ihnen auch, dass Ihr Parameter b nichts tut:
Globale variable Abschattung
Dieser ein bisschen schwer und zeigte sich nicht, bis
-Wshadow
verwendet wurde. Lassen Sie uns das obige Beispiel so ändern, dass es nur hinzugefügt wird, aber es gibt zufällig ein globales mit demselben Namen wie ein lokales, was bei dem Versuch, beide zu verwenden, viel Verwirrung stiftet.Wenn -Wshadow aktiviert war, ist dieses Problem leicht zu erkennen.
Zeichenfolgen formatieren
Dies erfordert keine zusätzlichen Flags in gcc, war jedoch in der Vergangenheit immer noch die Ursache für Probleme. Eine einfache Funktion, die versucht, Daten zu drucken, aber einen Formatierungsfehler aufweist, könnte folgendermaßen aussehen:
Dadurch wird die Zeichenfolge nicht gedruckt, da das Formatierungsflag falsch ist und gcc Ihnen gerne mitteilt, dass dies wahrscheinlich nicht das ist, was Sie wollten:
Dies sind nur drei der vielen Dinge, die der Compiler für Sie überprüfen kann. Es gibt viele andere, die gerne eine nicht initialisierte Variable verwenden, auf die andere hingewiesen haben.
quelle
possible loss of precision
" und "comparison between signed and unsigned
" Warnungen. Ich finde es schwierig zu verstehen, wie viele "Programmierer" diese ignorieren (tatsächlich bin ich mir nicht sicher, warum sie keine Fehler sind)sizeof
nicht signiert ist, sondern der Standard-Integer-Typ signiert ist. Dersizeof
Ergebnistypsize_t
wird normalerweise für alles verwendet, was mit der Typgröße zusammenhängt, z. B. Ausrichtung oder Anzahl der Array- / Containerelemente, während Ganzzahlen im Allgemeinen als "int
sofern nicht anders erforderlich" verwendet werden sollen. Wenn man bedenkt, wie viele Leute auf diese Weiseint
lernen, ihre Container zu durchlaufen (im Vergleichint
zusize_t
), würde ein Fehler ungefähr alles kaputt machen. ; PDies ist eine spezifische Antwort auf C, und warum dies für C weitaus wichtiger ist als für alles andere.
Dieser Code wird mit einer Warnung kompiliert . Was in nahezu jeder anderen Sprache auf dem Planeten Fehler sind und sein sollten (mit Ausnahme der Assemblersprache), sind Warnungen in C. Warnungen in C sind fast immer Verkleidungsfehler. Warnungen sollten behoben und nicht unterdrückt werden.
Mit machen
gcc
wir das alsgcc -Wall -Werror
.Dies war auch der Grund für die hohe Unzufriedenheit mit einigen nicht sicheren MS-API-Warnungen. Die meisten Leute, die C programmieren, haben gelernt, Warnungen als Fehler zu behandeln, und dieses Zeug schien einfach nicht dasselbe zu sein und wollte nicht tragbare Korrekturen.
quelle
COMPILER-WARNHINWEISE SIND IHR FREUND (nicht schreien, zur Hervorhebung in Großbuchstaben).
Ich arbeite an älteren Fortran-77-Systemen. Der Compiler sagt mir wertvolle Dinge: Der Datentyp des Arguments stimmt bei einem Unterprogrammaufruf nicht überein. Dabei wird eine lokale Variable verwendet, bevor ein Wert in die Variable festgelegt wurde, wenn ich ein nicht verwendetes Variablen- oder Unterprogrammargument habe. Dies sind fast immer Fehler.
Vermeiden eines langen Beitrags: Wenn mein Code sauber kompiliert wird, funktioniert er zu 97%. Der andere Typ, mit dem ich arbeite, kompiliert mit allen Warnungen, verbringt Stunden oder Tage im Debugger und bittet mich dann um Hilfe. Ich kompiliere nur seinen Code mit den Warnungen und sage ihm, was zu beheben ist.
quelle
Sie sollten Compiler-Warnungen immer aktivieren, da der Compiler Ihnen häufig mitteilen kann, was mit Ihrem Code nicht stimmt. Dazu übergeben Sie
-Wall -Wextra
an den Compiler.Sie sollten Warnungen normalerweise als Fehler behandeln, da die Warnungen normalerweise bedeuten, dass etwas mit Ihrem Code nicht stimmt. Es ist jedoch oft sehr einfach, diese Fehler zu ignorieren. Wenn Sie sie daher als Fehler behandeln, schlägt der Build fehl, sodass Sie die Fehler nicht ignorieren können. Um Warnungen als Fehler zu behandeln, übergeben Sie sie
-Werror
an den Compiler.quelle
Die Compiler-Warnungen in C ++ sind aus bestimmten Gründen sehr nützlich.
1 - Es erlaubt Ihnen zu zeigen, wo Sie einen Fehler gemacht haben können, der das Endergebnis Ihrer Operationen beeinflussen kann. Zum Beispiel, wenn Sie keine Variable initialisiert haben oder wenn Sie "=" anstelle von "==" setzen (es gibt nur Beispiele)
2 - Es erlaubt Ihnen auch zu zeigen, wo Ihr Code nicht dem Standard von c ++ entspricht. Dies ist nützlich, da es einfach ist, den Code in eine andere Plattenform zu verschieben, wenn der Code dem tatsächlichen Standard entspricht.
Im Allgemeinen sind die Warnungen sehr nützlich, um Ihnen zu zeigen, wo Sie Fehler in Ihrem Code haben, die das Ergebnis Ihres Algorithmus beeinflussen oder Fehler verhindern können, wenn der Benutzer Ihr Programm verwendet.
quelle
Das Ignorieren von Warnungen bedeutet, dass Sie schlampigen Code hinterlassen haben, der nicht nur in Zukunft Probleme für andere verursachen kann, sondern auch dazu führt, dass wichtige Kompilierungsnachrichten von Ihnen weniger wahrgenommen werden. Je mehr Compiler ausgegeben werden, desto weniger wird jemand bemerken oder stören. Je sauberer desto besser. Es bedeutet auch, dass Sie wissen, was Sie tun. Warnungen sind sehr unprofessionell, nachlässig und riskant.
quelle
Ich habe einmal für eine große Firma (Fortune 50) gearbeitet, die elektronische Testgeräte herstellte.
Das Kernprodukt meiner Gruppe war ein MFC-Programm, das im Laufe der Jahre buchstäblich Hunderte von Warnungen generierte. Welche wurden in fast allen Fällen ignoriert.
Dies ist ein verdammter Albtraum, wenn Fehler auftreten.
Nach dieser Position hatte ich das Glück, als erster Entwickler in einem neuen Startup eingestellt zu werden.
Ich habe eine Richtlinie "Keine Warnung" für alle Builds empfohlen, bei der die Compiler-Warnstufen ziemlich laut sind.
Unsere Praxis bestand darin, #pragma warning - push / disable / pop für Code zu verwenden, von dem der Entwickler sicher war, dass er wirklich in Ordnung ist, zusammen mit einer Protokollanweisung auf Debug-Ebene, nur für den Fall.
Diese Praxis hat bei uns gut funktioniert.
quelle
#pragma warning
unterdrückt nicht nur Warnungen, sondern dient dem doppelten Zweck, anderen Programmierern schnell mitzuteilen, dass etwas beabsichtigt und nicht zufällig ist, und dient als Such-Tag, um potenziell problematische Bereiche schnell zu lokalisieren, wenn etwas kaputt geht, die Fehler / Warnungen jedoch nicht repariere es.Eine Warnung ist ein Fehler, der darauf wartet, passiert zu werden. Sie müssen also Compiler-Warnungen aktivieren und Ihren Code aufräumen, um alle Warnungen zu entfernen.
quelle
Es gibt nur ein Problem bei der Behandlung von Warnungen als Fehler: Wenn Sie Code aus anderen Quellen verwenden (z. B. Micro $ ** t-Bibliotheken, Open Source-Projekte), haben sie ihre Arbeit nicht richtig gemacht, und das Kompilieren ihres Codes generiert Tonnen von Warnungen.
Ich immer meinen Code schreiben , so dass es keine Warnungen oder Fehler generiert, und reinigen Sie es , bis es kompiliert , ohne dass Nebengeräusche zu erzeugen. Der Müll, mit dem ich arbeiten muss, erschreckt mich und ich bin erstaunt, wenn ich ein großes Projekt erstellen und einen Strom von Warnungen beobachten muss, bei denen die Kompilierung nur ankündigen soll, welche Dateien sie verarbeitet hat.
Ich dokumentiere meinen Code auch, weil ich weiß, dass die tatsächlichen Lebenszeitkosten von Software hauptsächlich aus der Wartung stammen, nicht aus dem anfänglichen Schreiben, aber das ist eine andere Geschichte ...
quelle
-Wall
und du benutzt-Wall -Wextra
.Einige Warnungen können einen möglichen semantischen Fehler im Code oder eine mögliche UB bedeuten. ZB
;
nachif()
, nicht verwendete Variable, globale Variable, die durch lokale maskiert ist, oder Vergleich von vorzeichenbehafteten und vorzeichenlosen Variablen. Viele Warnungen beziehen sich auf den statischen Code-Analysator im Compiler oder auf Verstöße gegen den ISO-Standard, die zur Kompilierungszeit festgestellt werden können und "eine Diagnose erfordern". Während diese Vorkommnisse in einem bestimmten Fall legal sein können, sind sie meistens auf Designprobleme zurückzuführen.Einige Compiler, z. B. gcc, haben eine Befehlszeilenoption, um den Modus "Warnungen als Fehler" zu aktivieren. Dies ist ein nettes, wenn auch grausames Werkzeug, um unerfahrene Programmierer auszubilden.
quelle
Die Tatsache , dass C ++ Compiler Code kompiliert accept dass offensichtlich Ergebnisse in undefiniertem Verhalten überhaupt ein großer Fehler in dem Compiler ist. Der Grund, warum sie dies nicht beheben, ist, dass dies wahrscheinlich einige verwendbare Builds beschädigen würde.
Die meisten Warnungen sollten schwerwiegende Fehler sein, die den Abschluss des Builds verhindern. Die Standardeinstellungen, nur Fehler anzuzeigen und den Build trotzdem auszuführen, sind falsch. Wenn Sie sie nicht überschreiben, um Warnungen als Fehler zu behandeln und einige Warnungen zu hinterlassen, wird Ihr Programm wahrscheinlich abstürzen und zufällige Dinge tun.
quelle
int i; if (fun1()) i=2; if (fun2()) i=3; char s="abcde"[i];
Dieser Code zeigt nicht definiertes Verhalten , wenn und nur wenn beidefun1()
undfun2()
zurückgeben könnenfalse
auf dem gleichen Funktionsausführung. Was mag wahr sein oder nicht, aber wie soll der Compiler das sagen?Sie sollten auf jeden Fall Compiler-Warnungen aktivieren, da einige Compiler einige häufige Programmierfehler nicht melden können, darunter die folgenden: -
-> eine Variable initialisieren wird vergessen -> einen Wert von einer Funktion zurückgeben wird übersehen -> die einfachen Argumente in printf- und scanf-Familien, die nicht mit der Formatzeichenfolge übereinstimmen, die eine Funktion verwendet, ohne vorher deklariert zu werden, obwohl dies nur in c vorkommt
Da diese Funktionen erkannt und gemeldet werden können, ist dies normalerweise nicht standardmäßig der Fall. Daher muss diese Funktion explizit über Compileroptionen angefordert werden.
quelle
Nehmen Sie es ruhig: Sie müssen nicht, es ist nicht notwendig. -Wall and -Werror wurde von Code-Refactoring-Maniacs für sich selbst entwickelt: Es wurde von Compiler-Entwicklern erfunden, um zu vermeiden, dass vorhandene Builds nach Compiler-Updates auf der Benutzerseite beschädigt werden . Die Funktion ist nichts, aber alles über die Entscheidung, den Build zu brechen oder nicht zu brechen.
Es liegt ganz bei Ihnen, ob Sie es verwenden oder nicht. Ich benutze es die ganze Zeit, weil es mir hilft, meine Fehler zu beheben.
quelle
-Wall and -Werror was designed by code-refactoring maniacs for themselves.
[Zitat benötigt]-Wall
und-Werror
sie fragt nur, ob es eine gute Idee ist. Was aus Ihrem letzten Satz so klingt, als würden Sie sagen, dass es so ist.