Warum sollte man Compiler-Warnungen deaktivieren wollen?

26

Diese Antwort und die ihr hinzugefügten Kommentare zeigen eine Möglichkeit, mehrere Compiler-Warnungen mithilfe von #pragmaDirektiven zu deaktivieren .

Warum sollte man das tun wollen? Normalerweise gibt es die Warnungen aus einem bestimmten Grund, und ich habe immer das Gefühl, dass sie gute Gründe sind. Gibt es einen "gültigen Fall", in dem Warnungen deaktiviert werden sollten? Im Moment fällt mir nichts ein, aber vielleicht bin das nur ich.

takrl
quelle
4
Ich bin mir nicht sicher, warum jemand dies als nahe markiert hat. Scheint mir eine überaus vernünftige Frage zu sein. +1
@Alastair Pitts: Ich habe eine Migration zu Programmierern vorgeschlagen. Ich habe meinen Fehler später bemerkt.
Tugrul Ates
3
Die Warnmeldungen sind nicht ohne Grund vorhanden, aber es gibt auch einen Grund, warum sie keine Fehlermeldungen sind .
Solomon Slow
2
@jameslarge Ihr Kommentar fasst die Situation gut zusammen. Eine Warnung ist der Compiler, der Ihnen mitteilt, dass eine Situation plausibel falsch ist , was möglicherweise das Richtige impliziert . Wenn es definitiv falsch wäre, wäre es ein Fehler. Da einige Warnungen möglicherweise falsch positiv sind, sollte es immer eine Möglichkeit geben, Code so zu schreiben, dass die Warnung beseitigt wird. Leider ist es manchmal am pragmatischsten, dies über ein Pragma zu tun. daher der Name.
Eric Lippert
Es ist nicht deaktivierend, es versteckt sich. Das Problem wird immer noch da sein, nur dass Sie es nicht so sehen werden, wie es ist
Sisir

Antworten:

11

Ich hatte bisher nur eine Situation, in der ich eine Warnung deaktiviert habe. Ich betrachte Warnungen als Fehler, daher würde ich sie normalerweise nicht mit Warnungen veröffentlichen. Bei der Entwicklung einer API bei einem Kunden stellte sich jedoch das Problem, dass eine Methode, die in einer Migrationsphase von einer Anwendung benötigt wurde und von keiner anderen Anwendung verwendet werden sollte, in die Bibliothek aufgenommen werden musste.

Die beste Möglichkeit, allen Benutzern der API mitzuteilen, dass sie diese Methode nicht aufrufen sollten, bestand darin, sie als veraltet zu markieren. Dies bedeutete jedoch, dass der eine gültige Anwendungsfall als Kompilierungswarnung markiert wurde.

Eric Lippert hat einige Posts über Warnungen geschrieben, in denen Sie Informationen darüber finden, wie das Compilerteam über Warnungen denkt.

Interne Felder von Internen Typen

Nicht verwendete Anweisungen sind nicht mit Warnungen versehen

Rune FS
quelle
10

Hier sind einige Warnungen, in denen die Dokumentation Gründe dafür enthält, warum Sie sie möglicherweise deaktivieren möchten:

Andere Beispiele sind Warnungen zur Verwendung veralteter Methoden, wenn Sie wissen, dass Sie immer noch die alte Methode verwenden möchten oder private Mitglieder haben möchten, die nie lokal gelesen werden, sondern nur mit Reflektion.

Meiner Erfahrung nach muss C # Warnungen weniger deaktivieren als andere Sprachen wie C ++. Dies liegt vor allem daran, dass Eric Lippert in seinem Blog sagt , dass er versucht, "Warnungen nur für Situationen zu reservieren, in denen wir mit fast Sicherheit sagen können, dass der Code fehlerhaft, irreführend oder nutzlos ist".

ICR
quelle
3
Nett. Ich denke, das erste ist am klarsten, weil es einen sehr spezifischen Fall und eine Rechtfertigung bietet (das dritte zeigt zum Beispiel einen Teil des Codes, der für mein Team keine Prüfung bestehen würde). In dieser Frage geht es um veraltete / unangemessene Warnungen. Grundsätzlich werden sie im Legacy-Code weiterhin benötigt, aber Sie möchten jeden neuen Code davon abhalten, sie zu verwenden. Im Legacy-Code sollten die Warnungen unterdrückt sein.
Greg Jackson
Ich habe eine Menge Makroprogramme in Excel ausgeführt und musste Warnungen aus verschiedenen Gründen deaktivieren, wie z. B. Auto-Speichern, Auto-Beenden, Benachrichtigungen usw. Natürlich sind Sie bei diesen Warnungen nicht auf dem Laufenden ...
Dave Mess
@ICR Ich kann mich überhaupt nicht erinnern, Compiler-Warnungen in Java deaktiviert zu haben. Alles, was ich tue, ist zu vermeiden, veraltete Methoden zu verwenden.
Mahmoud Hossam
@Mahmoud Ich muss sehr oft "ungeprüfte" Warnungen unterdrücken, wenn ich etwas mache, das mit Generika sogar aus der Ferne komplex ist. Aber es ist wahrscheinlich unfair, Java in den lächerlichen Warnungen von C ++ einzubeziehen - meine Antwort wurde überarbeitet.
ICR
@ICR Java erzwingt die Verwendung von Generika, um die Typensicherheit in Auflistungen zu gewährleisten. Einige sehen dies als Einschränkung, ich betrachte es als eine Funktion, die das Schreiben von Code etwas schmerzhaft macht, aber Leben rettet, und ja, die C ++ - Compiler-Ausgabe ist etwas beängstigend, wenn es um STL oder etwas mit Vorlagen geht.
Mahmoud Hossam
8

Ein Beispiel in C, das mir regelmäßig begegnet:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

Das Argument ist nur auf einigen Plattformen relevant, aber auf solchen, auf denen es nicht relevant ist, wird sich mein Compiler beschweren, und da ich Warnungen in Fehler umgewandelt habe, wird verhindert, dass sie erstellt werden.

Das Konvertieren von Warnungen in Fehler erfordert eine Escape-Luke für "nicht diese, ich weiß es in diesem Fall besser als der Compiler".

pjc50
quelle
6

Viele unverzichtbare Java-Bibliotheken wurden nie aktualisiert, um unsichere Typecasts zu vermeiden. Das Unterdrücken dieser Warnungen ist erforderlich, damit andere wichtigere Warnungen bemerkt und korrigiert werden.

Kevin Cline
quelle
5

Ich mache Embedded-Arbeiten und erinnere mich an ein oder zwei Male, als ich Warnungen deaktiviert habe, weil ich etwas gemacht habe, das für den Compiler nutzlos aussah, aber tatsächlich reale Auswirkungen auf die Hardware hatte.

Das einzige andere Mal, wenn ich an Codebasen mit unterschiedlichen Vorstellungen einer Datenstruktur arbeite (z. B. wie man Bytearrays darstellt - char oder unsigned char?). In diesen Fällen kann es sein, dass ich die Warnungen deaktiviere, weil die Alternative darin besteht, Tage damit zu verbringen, den Code zu durchlaufen und entweder einen Teil zu ändern oder Hunderte von Casts einzugeben.

Michael Kohne
quelle
3

Es gibt einige Gründe, Compiler-Warnungen selektiv zu deaktivieren, auch für Projekte, die nach Best Practices streben.

  • Verschiedene Compiler (oder verschiedene Versionen derselben Compiler) :
    Compiler behandeln Warnungen auf subtile Weise. Geben Sie falsch positive Warnungen aus, die sich nicht auf andere Compiler auswirken. In diesem Fall ist es möglicherweise sinnvoll, die Warnung für diese Compiler zu deaktivieren, anstatt gültigen Code zu bearbeiten, um eine falsch-positive Warnung zu unterdrücken, die nur bestimmte Compiler betrifft, insbesondere ältere Compiler, die möglicherweise ohnehin nicht mehr unterstützt werden.
  • Mit generiertem Code:
    Einige Warnungen im Zusammenhang mit der Codehygiene (toter Code, doppelter Text bedingter Anweisungen, Vergleiche, die die Typgrenzen überschreiten) können ignoriert werden, da sie harmlos sind und vom Compiler optimiert werden.
    Das Generieren von Code, der diese harmlosen Warnungen nicht auslöst, ist natürlich ebenfalls eine Option, kann aber mehr Probleme bereiten als es sich lohnt.
  • Warnungen für externen Code:
    Möglicherweise verwenden Sie eine bekannte qsort- oder md5-Prüfsummenimplementierung, die in Ihrem Projekt enthalten ist. Der Code wird von vielen Projekten verwendet und funktioniert bekanntermaßen gut. Es kann jedoch einige wählerische Warnungen geben, die Sie normalerweise für Ihren eigenen Code korrigieren.
    Jedoch für externen Code, kann es weniger Aufwand sein, nur die Warnung abzuschalten (vorausgesetzt , seine definitiv ist harmlos).
  • Durch Systemheader verursachte Warnungen:
    Auch wenn beispielsweise GCC / Clang unterstützt -isystem, gibt es Fälle, in denen Unterschiede in den Systemheader Warnungen verursachen, die ignoriert werden können (möglicherweise hat eine Funktion auf einem System einen vorzeichenbehafteten Rückgabewert, auf einem anderen jedoch keinen) und -Wsign-compareWarnungen auslösen .
    Ein anderer Fall können Makros sein, die in System-Headern definiert sind. Sie können die Makros kopieren und in Ihren eigenen Code einfügen, um sie zu ändern, aber alles in allem ist es besser, sich keine Sorgen um die Verwaltung von Makros aus Bibliotheken von Drittanbietern zu machen um die Warnung zu beruhigen (vielleicht fehlt dem Makro eine Besetzung, die -Wsign-conversionz. B. verursacht ).
  • Nicht verwendete Warnungen im Stub-Code:
    Sie können vor nicht verwendeten Parametern warnen, wenn Sie jedoch eine gesamte Bibliothek in einer einzelnen Datei stubben, die nur Stub-Funktionen enthält - es ist nicht hilfreich, (void)arg1; (void)arg2; (void)arg3; ...den Rumpf jeder Stub-Funktion zu erzwingen .
    Besser einfach -Wunused-parameterin diesem Fall unterdrücken .

Beachten Sie, dass in allen diesen Beispielen seine die Warnungen angenommenen Deaktivierung ist nicht wirklich Fehler gehen zu verbergen, zum Beispiel: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, vielleicht -Wpedantic... und dass Sie wissen , was Sie tun!

ideasman42
quelle
2

Gültig oder nicht, manchmal wird die Anweisung "Warnungen als Fehler behandeln" auf dem Build-Server umgangen.

Ansonsten fällt mir auch nichts ein. Deaktivierte Warnungen sind normalerweise ein Zeichen für einen "hässlichen Hax" ...

David Božjak
quelle
2

Als wir das letzte Mal bestimmte Warnungen deaktiviert haben, war dies darauf zurückzuführen, dass uns ein Praktikant einen schlechten Code hinterlassen hatte. Ich habe es viel besser funktionieren, mit klaren Konvertierungsgrenzen, die die zufällige Datendarstellung ersetzen.

In der Zwischenzeit mussten wir es kompilieren und wollten, dass die Option "Warnungen sind Fehler" aktiviert ist. Daher haben wir einige der Warnungen unterdrückt.

David Thornley
quelle
2

Derzeit ist die einzige Warnung, die ich jemals ignoriere

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Weil Microsoft die C ++ - Spezifikation nicht implementiert (die Dokumentation sagt sogar, dass dies nicht der Fall ist!) Und es Funktionen erlaubt, bestimmte Würfe zu deklarieren, und alle Funktionen können nur entweder throw () oder throw (...), dh nichts oder alles, werfen.

In HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
Casey
quelle