In Visual C ++ ist die Verwendung möglich #pragma warning (disable: ...)
. Außerdem habe ich festgestellt, dass Sie in GCC die Compiler-Flags pro Datei überschreiben können . Wie kann ich dies für "nächste Zeile" oder mit Push / Pop-Semantik in Codebereichen mithilfe von GCC tun?
c
gcc
compiler-warnings
pragma
Matt Joiner
quelle
quelle
Antworten:
Es scheint, dass dies getan werden kann . Ich kann die hinzugefügte Version von GCC nicht bestimmen, aber es war einige Zeit vor Juni 2010.
Hier ist ein Beispiel:
quelle
push
und zweipop
s - kann ein anderespush
am anfang fehlen?Dies ist ein Beispiel für die vorübergehende Deaktivierung einer Warnung:
Weitere Informationen finden Sie in der GCC-Dokumentation zu diagnostischen Pragmas .
quelle
gcc-4.9
ignoriere diese Zeile einfach komplett.TL; DR : Wenn es funktioniert, vermeiden oder verwenden Sie
__attribute__
andere Bezeichner_Pragma
.Dies ist eine Kurzversion meines Blog-Artikels Unterdrückte Warnungen in GCC und Clang .
Folgendes berücksichtigen
Makefile
zum Erstellen des folgenden
puts.c
QuellcodesEs wird da nicht kompiliert
argc
es nicht verwendet wird und die Einstellungen hardcore sind (-W -Wall -pedantic -Werror
) sind.Es gibt 5 Dinge, die Sie tun könnten:
__attribute__
_Pragma
#pragma
Quelle verbessern
Der erste Versuch sollte darin bestehen, zu überprüfen, ob der Quellcode verbessert werden kann, um die Warnung zu entfernen. In diesem Fall möchten wir den Algorithmus nicht nur deswegen ändern, da er
argc
mit!*argv
(NULL
nach dem letzten Element) .Verwenden eines Deklarationsspezifizierers wie
__attribute__
Wenn Sie Glück haben, bietet der Standard einen Spezifizierer für Ihre Situation, wie z
_Noreturn
.__attribute__
ist eine proprietäre GCC-Erweiterung (wird auch von Clang und einigen anderen Compilern unterstütztarmcc
) und wird von vielen anderen Compilern nicht verstanden. Fügen Sie__attribute__((unused))
ein Makro ein, wenn Sie portablen Code möchten._Pragma
Operator_Pragma
kann als Alternative zu verwendet werden#pragma
.Der Hauptvorteil des
_Pragma
Operators besteht darin, dass Sie ihn in Makros einfügen können, was mit der#pragma
Direktive nicht möglich ist .Nachteil: Es ist fast ein taktischer Nuke, da es zeilenbasiert statt deklarationsbasiert funktioniert.
Der
_Pragma
Betreiber wurde in C99 eingeführt.#pragma
Richtlinie.Wir könnten den Quellcode ändern, um die Warnung für einen Codebereich zu unterdrücken, normalerweise eine ganze Funktion:
Nachteil: Es ist fast ein taktischer Nuke, da es zeilenbasiert statt deklarationsbasiert funktioniert.
Beachten Sie, dass eine ähnliche Syntax in clang vorhanden ist .
Unterdrücken der Warnung in der Befehlszeile für eine einzelne Datei
Wir könnten die folgende Zeile hinzufügen
Makefile
, um die Warnung speziell für Puts zu unterdrücken:Dies ist wahrscheinlich nicht erwünscht, was Sie in Ihrem speziellen Fall wollen, aber es kann anderen Lesungen helfen, die sich in ähnlichen Situationen befinden.
quelle
improving the source
Es würde auch funktionieren, die Deklaration von main in zu ändern,int main(int, const char* argv[]) { ... }
indem dem Argument kein Name gegeben wird. Sie teilen dem Compiler mit, dass es nicht verwendet wird.gcc
sowieclang
.#define UNUSED(x) ((void)x)
verwendet, um Warnungen auszuschalten. Ich denke es war in ReactOS?_Pragma("GCC diagnostic pop") \
sollte nur sein,_Pragma("GCC diagnostic pop")
denke ich.Dies sollte den Trick für gcc, clang und msvc tun
Kann aufgerufen werden mit zB:
Siehe https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html , http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas und https://msdn.microsoft Weitere Informationen finden Sie unter .com / de-DE / library / d9x1s805.aspx
Sie benötigen mindestens Version 4.02, um diese Art von Pragmas für gcc zu verwenden. Sie sind sich nicht sicher über msvc und klirren über die Versionen.
Es sieht so aus, als ob das Push-Pop-Pragma-Handling für gcc etwas kaputt ist. Wenn Sie die Warnung erneut aktivieren, wird weiterhin die Warnung für den Block angezeigt, der sich im Block DISABLE_WARNING / ENABLE_WARNING befand. Für einige Versionen von gcc funktioniert es, für andere nicht.
quelle
Ersetzen Sie "-Wformat" durch den Namen Ihres Warnflags.
AFAIK Es gibt keine Möglichkeit, die Push / Pop-Semantik für diese Option zu verwenden.
quelle
Ich hatte das gleiche Problem mit externen Bibliotheken wie ROS-Headern. Ich verwende gerne die folgenden Optionen in CMakeLists.txt für eine strengere Kompilierung:
Dies führt jedoch auch in extern eingeschlossenen Bibliotheken zu allen Arten von pedantischen Fehlern. Die Lösung besteht darin, alle pedantischen Warnungen zu deaktivieren, bevor Sie externe Bibliotheken einschließen, und diese wie folgt erneut zu aktivieren:
quelle
Ich weiß, die Frage bezieht sich auf GCC, aber für Leute, die suchen, wie dies in anderen und / oder mehreren Compilern gemacht werden kann ...
TL; DR
Vielleicht möchten Sie einen Blick auf Hedley werfen , einen gemeinfreien C / C ++ - Header, den ich geschrieben habe und der viel bewirkt für Sie . Ich werde am Ende dieses Beitrags einen kurzen Abschnitt über die Verwendung von Hedley für all dies einfügen.
Warnung deaktivieren
#pragma warning (disable: …)
hat Äquivalente in den meisten Compilern:#pragma warning(disable:4996)
#pragma GCC diagnostic ignored "-W…"
wobei die Ellipse der Name der Warnung ist; zB ,#pragma GCC diagnostic ignored "-Wdeprecated-declarations
.#pragma clang diagnostic ignored "-W…"
. Die Syntax ist im Grunde die gleiche wie bei GCC, und viele der Warnnamen sind gleich (obwohl viele nicht).#pragma warning(disable:1478 1786)
.diag_suppress
Pragma:#pragma diag_suppress 1215,1444
diag_suppress
Pragma mit derselben Syntax (aber unterschiedlichen Warnnummern!) Wie PGI:pragma diag_suppress 1291,1718
error_messages
Pragma. Ärgerlicherweise unterscheiden sich die Warnungen für die C- und C ++ - Compiler. Beide deaktivieren im Grunde die gleichen Warnungen:#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
#pragma error_messages(off,symdeprecated,symdeprecated2)
diag_suppress
wie PGI und TI, aber die Syntax ist unterschiedlich. Einige der Warnnummern sind die gleichen, aber ich andere sind auseinander gegangen:#pragma diag_suppress=Pe1444,Pe1215
#pragma warn(disable:2241)
Für die meisten Compiler ist es oft eine gute Idee, die Compilerversion zu überprüfen, bevor Sie versuchen, sie zu deaktivieren. Andernfalls wird nur eine weitere Warnung ausgelöst. Zum Beispiel hat GCC 7 Unterstützung für die
-Wimplicit-fallthrough
Warnung hinzugefügt. Wenn Sie sich also für GCC vor 7 interessieren, sollten Sie so etwas tunBei Clang und Compilern, die auf Clang basieren, wie z. B. neueren Versionen von XL C / C ++ und Armclang, können Sie mithilfe des
__has_warning()
Makros überprüfen, ob der Compiler über eine bestimmte Warnung informiert ist .Natürlich müssen Sie auch überprüfen, ob das
__has_warning()
Makro vorhanden ist:Sie könnten versucht sein, so etwas zu tun
So können Sie
__has_warning
etwas einfacher verwenden. Clang schlägt__has_builtin()
in ihrem Handbuch sogar etwas Ähnliches für das Makro vor. Tu das nicht . Andere Codes suchen möglicherweise nach__has_warning
Compilerversionen und greifen auf diese zurück, wenn sie nicht vorhanden sind. Wenn Sie definieren__has_warning
, wird der Code beschädigt. Der richtige Weg, dies zu tun, besteht darin, ein Makro in Ihrem Namespace zu erstellen. Beispielsweise:Dann kannst du Sachen wie machen
Schieben und knallen
Viele Compiler unterstützen auch die Möglichkeit, Warnungen auf einen Stapel zu übertragen. Dadurch wird beispielsweise eine Warnung in GCC für eine Codezeile deaktiviert und anschließend in den vorherigen Status zurückgesetzt:
Natürlich gibt es zwischen den Compilern keine große Übereinstimmung hinsichtlich der Syntax:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
#pragma clang diagnostic push
/#pragma diagnostic pop
#pragma warning(push)
/#pragma warning(pop)
#pragma warning(push)
/#pragma warning(pop)
#pragma push
/#pragma pop
#pragma diag_push
/#pragma diag_pop
#pragma warning(push)
/#pragma warning(pop)
Wenn Speicher dient, mussten für einige sehr alte Versionen von GCC (wie 3.x, IIRC) die Push / Pop-Pragmas außerhalb der Funktion liegen.
Versteckt die blutigen Details
Für die meisten Compiler ist es möglich, die Logik hinter Makros mit zu verbergen
_Pragma
, die in C99 eingeführt wurde. Selbst im Nicht-C99-Modus unterstützen die meisten Compiler_Pragma
. Die große Ausnahme ist MSVC, das ein eigenes__pragma
Schlüsselwort mit einer anderen Syntax hat. Der Standard verwendet_Pragma
eine Zeichenfolge, die Microsoft-Version nicht:Ist ungefähr gleichbedeutend mit einmal vorverarbeitet zu
Auf diese Weise können wir Makros erstellen, damit wir Code wie schreiben können
Und verstecken Sie alle hässlichen Versionsprüfungen in den Makrodefinitionen.
Der einfache Weg: Hedley
Jetzt, da Sie die Mechanik verstehen, wie man solche Dinge portabel macht, während Sie Ihren Code sauber halten, verstehen Sie, was eines meiner Projekte ist, Hedley . Anstatt Tonnen von Dokumentation zu durchsuchen und / oder so viele Versionen von so vielen Compilern wie möglich zu installieren, können Sie einfach Hedley (es ist ein einzelner gemeinfreier C / C ++ - Header) einbinden und damit fertig sein. Beispielsweise:
Deaktiviert die Warnung zum Aufrufen einer veralteten Funktion für GCC, Clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles und möglicherweise andere (ich werde diese Antwort wahrscheinlich nicht aktualisieren, wenn ich Hedley aktualisiere). Und auf Compilern, von denen nicht bekannt ist, dass sie funktionieren, werden die Makros zu nichts vorverarbeitet, sodass Ihr Code weiterhin mit jedem Compiler funktioniert. Natürlich
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
ist Hedley nicht die einzige Warnung, von der Hedley weiß, und das Deaktivieren von Warnungen ist nicht alles, was Hedley tun kann, aber hoffentlich haben Sie die Idee.quelle
Anstatt die Warnungen zum Schweigen zu bringen, verwendet der gcc-Stil normalerweise entweder Standard-C-Konstrukte oder die
__attribute__
Erweiterung, um dem Compiler mehr über Ihre Absicht zu erzählen. Zum Beispiel wird die Warnung über die als Bedingung verwendete Zuweisung unterdrückt, indem die Zuweisung in Klammern gesetzt wird, dhif ((p=malloc(cnt)))
anstelle vonif (p=malloc(cnt))
. Warnungen vor nicht verwendeten Funktionsargumenten können durch seltsame Ereignisse, an die__attribute__
ich mich nie erinnern kann, oder durch Selbstzuweisung usw. unterdrückt werden . Im Allgemeinen ziehe ich es jedoch vor, Warnoptionen, die Warnungen für Dinge generieren, die im richtigen Code auftreten, nur global zu deaktivieren.quelle
if ((p=malloc(cnt)) != NULL) ...
, dass der Compiler dies hinter den Kulissen tut.Wenn Sie diese Seite gefunden haben und nach einer Möglichkeit suchen, dies in IAR zu tun, versuchen Sie Folgendes:
Weitere Informationen finden Sie unter http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html .
quelle