Wie deaktiviere ich Warnungen für bestimmte Include-Dateien?

78

Ich möchte bestimmte Warnungen für alle Dateien deaktivieren, die direkt oder indirekt von bestimmten Include-Dateien enthalten sind. Zum Beispiel möchte ich die Warnung "Sie weisen einem Zeichen * ein Zeichenfolgenliteral zu" für alle Dateien oder Dateien deaktivieren, die in Dateien enthalten sind, die in a enthalten sind #include <bar/*>(der Stern bedeutet in meinem Fall "alles kann hier sein").

Der Grund ist, dass einige der Leute, mit denen ich programmieren muss, "const" einfach nicht verwenden können, so dass ich am Ende viele Warnungen über diesen bestimmten Missbrauch von String-Literalen bekomme. Ich möchte diese Tausenden von Warnungen aus ihrem Code ignorieren, damit ich mich auf die Fehler in meinem eigenen Code konzentrieren und sie beheben kann.

Ich benutze Intel C ++ und GCC. Einige meiner Freunde verwenden Clang, daher würde ich mich auch über Lösungen freuen.

Johannes Schaub - litb
quelle
Verstehe ich das richtig - wenn eine fragliche Datei von enthalten ist <bar/the_file.h>, sollten die Warnungen unterdrückt werden und <the_file.h>nicht?
Xeo
@Neil danke für die verwandten Links. Nur um anderen klar zu machen, die möglicherweise unerwünschte Assoziationen haben: Die beiden oben genannten Links sind keine betrogenen Links!
Johannes Schaub - litb
@Xeo das nicht besonders. Ich kann damit leben, dass alle Warnungen für diese Datei deaktiviert sind. Es muss kein bestimmtes Include-Muster haben. Ich vermute, dass die Art und Weise, wie ich meine Frage formuliert habe, etwas unglücklich ist.
Johannes Schaub - litb
Welchen Compiler verwenden Sie? (Methoden zur Unterdrückung von Warnungen unterscheiden sich häufig je nach Compiler.)
Ben Hocking

Antworten:

71

Wenn Sie GCC verwenden, können Sie das -isystemFlag anstelle des -IFlags verwenden, um Warnungen von diesem Speicherort aus zu deaktivieren.

Also, wenn Sie gerade verwenden

gcc -Iparent/path/of/bar …

verwenden

gcc -isystem parent/path/of/bar …

stattdessen. Leider ist dies keine besonders feinkörnige Steuerung. Mir ist kein gezielterer Mechanismus bekannt.

Konrad Rudolph
quelle
4
in clang gibt es --system-header-prefix = option, siehe clang.llvm.org/docs/…
dev_null
47

Eine bessere GCC-Lösung: Verwenden Sie #pragma.

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-W<evil-option>"
#include <evil_file>
#pragma GCC diagnostic pop

zum Beispiel:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QtXmlPatterns>
#pragma GCC diagnostic pop
Brad
quelle
Das will ich nicht. Ich suche nach einer Möglichkeit, Warnungen für alle Dateien zu deaktivieren, die mit "Qt" beginnen (um Ihr Beispiel beizubehalten. Nicht nur für eine einzelne benannte Datei. Wir verwenden bereits Diagnose-Push / Pop, dies kann jedoch leider keine Platzhalterübereinstimmung für Dateinamen durchführen soweit wir gesehen haben.
Johannes Schaub - litb
Entschuldigung, ich habe es falsch verstanden. AFAIK, Sie haben nur zwei Möglichkeiten: Erstellen Sie eine Header-Datei, die alle fraglichen Header enthält, die in die # Pragma-Diagnose eingeschlossen ist, und fügen Sie sie zuerst ein (und verlassen Sie sich auf Multi-Inclusion-Guards, um die Dateien nur einmal zu verarbeiten). Oder behandeln Sie die Header als System-Header mit -isystem. Ich glaube nicht, dass es eine Möglichkeit gibt, benutzerdefinierte Diagnoseregeln basierend auf dem Include-Pfad zu definieren (über das Verhalten des Isystems hinaus). Ich habe für dieses Problem immer den Ansatz "create a" include_all_bar.h "file" verwendet.
Brad
12
Ich muss sagen, dass diese Antwort zwar nicht von oben gewählt wurde, aber ich denke, dass sie sehr nützlich ist. Obwohl es nicht ganz der ursprünglichen Frage entspricht (alle Bibliotheken in einem Pfad / Präfix), bietet es eine Möglichkeit, einige Warnungen für einen bestimmten Satz von Headern selektiv auszuschließen. 👍
Benschumacher
35

Wenn ich g++Header von Drittanbietern verwende, habe ich Tonnen von Warnungen mit meinen üblichen Standardeinstellungen von -Wall -Wextra& co. Ich neige dazu, sie in separaten Includes zu gruppieren und die anzugeben .system_header #pragma

[...] GCC gibt Code, der in Systemheadern enthalten ist, eine Sonderbehandlung. Alle Warnungen außer denen, die von generiert wurden #warning(siehe Diagnose), werden unterdrückt, während GCC einen Systemheader verarbeitet. In einem Systemheader definierte Makros sind überall dort, wo sie erweitert werden, gegen einige Warnungen immun. Diese Immunität wird auf Ad-hoc-Basis gewährt, wenn wir feststellen, dass eine Warnung aufgrund von Code in Makros, die in Systemheadern definiert sind, viele Fehlalarme generiert.

[...]

Es gibt auch eine Anweisung, #pragma GCC system_headerdie GCC anweist, den Rest der aktuellen Include-Datei als Systemheader zu betrachten, unabhängig davon, wo sie gefunden wurde. Code, der vor dem #pragmain der Datei steht, ist nicht betroffen. #pragma GCC system_headerhat keine Auswirkung auf die primäre Quelldatei.

Ich ziehe diese Lösung der vor -isystem, weil sie feinkörniger ist und ich sie direkt in die Quellen einfügen kann, ohne zu viel mit Befehlszeilenargumenten und Verzeichnissen zu tun zu haben.

Beispiel mit der schrecklichen Stammbibliothek:

#ifndef ROOTHEADERS_HPP_INCLUDED
#define ROOTHEADERS_HPP_INCLUDED
#ifdef __GNUC__
// Avoid tons of warnings with root code
#pragma GCC system_header
#endif
#include "TH1F.h"
#include "TApplication.h"
#include "TGraph.h"
#include "TGraph2D.h"
#include "TCanvas.h"
#endif
Matteo Italia
quelle
2
Oh, sehr gut. +1… leider kommen solche Dateien in der Regel vor anderen Include-Dateien und das Anwenden des Pragmas scheint den Rest der Datei zu beeinflussen, dh alle folgenden Includes.
Konrad Rudolph
@Konrad Rudolph: Bist du dir da sicher? ist es nicht nur für ein Include und seine Sub-Includes?
Amir Zadeh
1
@Green Ja, das habe ich gemeint. Dies erfordert jedoch, dass ich entweder alle fragwürdigen Includes am Ende der Include-Liste einfüge (und wie gesagt, das ist oft nicht wünschenswert oder sogar möglich) oder alle fraglichen Includes in einen separaten Header einfügt, den Sie dann einschließen. Dies ist auch keine perfekte Option in einem großen Verbundprojekt.
Konrad Rudolph
2
@Konrad: Die zweite Lösung ist die, die ich angenommen habe.
Matteo Italia
0

Ich denke, die einfachste Lösung wäre, ein einfaches Skript zu schreiben, das den Compiler aufruft, die unerwünschte Ausgabe basierend auf dem Dateinamen und dem Warnungstyp kompiliert und entfernt. Sie können für jeden Compiler unterschiedliche Skripte verwenden.

Aktualisieren Sie einfach Ihr Makefile, um dieses Skript zu verwenden, anstatt den Compiler direkt aufzurufen.

Gilad Naor
quelle