GCC-Warnungen nur für einen Teil einer Übersetzungseinheit selektiv deaktivieren?

85

Was ist das nächstgelegene GCC-Äquivalent zu diesem MSVC-Präprozessorcode?

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

Wir haben Code in häufig enthaltenen Headern, für die wir keine spezifische Warnung generieren möchten. Wir möchten jedoch, dass Dateien, die diese Header enthalten, diese Warnung weiterhin generieren (wenn für das Projekt diese Warnung aktiviert ist).

Jon-Eric
quelle
Wenn die Header in / usr / include installiert sind oder was Sie haben, generiert gcc standardmäßig keine Warnungen für sie.
Spudd86

Antworten:

95

Dies ist in GCC seit Version 4.6 oder um Juni 2010 im Trunk möglich.

Hier ist ein Beispiel:

#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */
Matt Joiner
quelle
8
Die Push- und Pop-Funktionalität wurde in gcc 4.6 ( gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html ) hinzugefügt .
Dave Johansen
Sie werden wahrscheinlich zweimal pushen wollen, wenn Sie zweimal knallen wollen.
Dan
2
@ Dan: Lesen Sie das Handbuch und kommentieren Sie. Beachten Sie den Ursprung des Beispiels.
Matt Joiner
Zu Ihrer Information, für ältere Versionen wie 4.4.7 können Sie das weiterhin verwenden, #pragma GCC diagnostic [error|warning|ignored]aber das popist nicht implementiert / unterstützt.
Trevor Boyd Smith
36

Die nächste Sache ist die GCC - Diagnose Pragma , #pragma GCC diagnostic [warning|error|ignored] "-Wwhatever". Es ist nicht sehr nah an dem, was Sie wollen, und siehe den Link für Details und Einschränkungen.

Chaos
quelle
1
Wissen Sie, was und wo die Gründe dafür sein könnten, diese Funktion nicht hinzuzufügen? (Ich konnte es nicht finden.) Ich finde die Warnung Push-Disable-Pop nützlich.
1
Ich kann mir nicht wirklich vorstellen, dass das "Nicht-Hinzufügen von Features" zu gcc eher eine Begründung hat als die Abwesenheit von jemandem, der einen funktionierenden Patch einreicht.
Chaos
14
Es ist nicht so, dass niemand bereit ist, die Arbeit für diese Art von feinkörniger Warnkontrolle in gcc zu erledigen oder den Code einzureichen - ich kenne einen großen Silicon Valley-Konzern, der dies bereits getan hat, und einen anderen, der sich gefreut hätte, jemanden zu bezahlen um es zu tun und den Code in den Stream zu bekommen. Nach einer Diskussion mit einem Mann, der (als einer der GDB-Betreuer) in dieses Zeug eingebunden ist, haben die GCC-Betreuer eine Philosophie: "Wenn es eine Warnung gibt, ist es ein Fehler, und Sie müssen ihn beheben." Also (imo) ist es ein religiöses Argument, und sie kontrollieren den Code, damit sie gewinnen.
Bob Murphy
Um Bobs Kommentar zu ergänzen, haben die GCC-Entwickler die #pragmaRichtlinie in der Vergangenheit abgelehnt , sodass alles, was GCC-spezifisch ist, wahrscheinlich eher als implementiert wird __attribute__((foo)).
Tom
10
neue gcc (> = 4.4) hat, #pragma GCC push_optionsso dass Sie mit mehr als nur Diagnose herumspielen können
Spudd86
33

Ich habe etwas Ähnliches gemacht. Für Code von Drittanbietern wollte ich überhaupt keine Warnungen sehen. Also, anstatt zu spezifizieren -I/path/to/libfoo/include, habe ich verwendet -isystem /path/to/libfoo/include. Dadurch behandelt der Compiler diese Header-Dateien zum Zweck von Warnungen als "System-Header". Solange Sie sie nicht aktivieren -Wsystem-headers, sind Sie größtenteils sicher. Ich habe immer noch ein paar Warnungen gesehen, aber es reduziert den größten Teil des Mülls.

Beachten Sie, dass dies nur dann hilfreich ist, wenn Sie den fehlerhaften Code nach include-directory isolieren können. Wenn es sich nur um eine Teilmenge Ihres eigenen Projekts handelt oder mit anderem Code vermischt ist, haben Sie kein Glück.

Tom
quelle
1
Toller Tipp. Wenn Sie LLVM verwenden, fügen Sie das Flag -isystem unter "Andere C-Flags" im Abschnitt "Apple LLVM Compiler - Sprache" hinzu.
Nestor
@ Tom Danke fürs Teilen. Ich kann nicht verstehen, wo ich Ihre Lösung verwenden soll. Kannst du noch ein bisschen mehr sagen?
Lorenzo B
1

Dies ist eine Erweiterung der Antwort von Matt Joiner .

Wenn Sie nicht überall in Ihrem Code Pragmas erzeugen möchten, können Sie den Operator _Pragma verwenden :

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error
Cássio Renan
quelle