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:
- MSVC:
#pragma warning(disable:4996)
- GCC:
#pragma GCC diagnostic ignored "-W…"
wobei die Ellipse der Name der Warnung ist; zB , #pragma GCC diagnostic ignored "-Wdeprecated-declarations
.
- klirren:
#pragma clang diagnostic ignored "-W…"
. Die Syntax ist im Grunde die gleiche wie bei GCC, und viele der Warnnamen sind gleich (obwohl viele nicht).
- Intel C Compiler: Verwenden Sie die MSVC-Syntax, beachten Sie jedoch, dass die Warnnummern völlig unterschiedlich sind. Beispiel:
#pragma warning(disable:1478 1786)
.
- GgA: Es gibt ein
diag_suppress
Pragma:#pragma diag_suppress 1215,1444
- TI: Es gibt ein
diag_suppress
Pragma mit derselben Syntax (aber unterschiedlichen Warnnummern!) Wie PGI:pragma diag_suppress 1291,1718
- Oracle Developer Studio (suncc): Es gibt ein
error_messages
Pragma. Ärgerlicherweise unterscheiden sich die Warnungen für die C- und C ++ - Compiler. Beide deaktivieren im Grunde die gleichen Warnungen:
- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C ++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- IAR: Verwendet auch
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
- Pelles C: ähnlich wie MSVC, auch hier sind die Zahlen unterschiedlich
#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 tun
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Bei 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 .
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Natürlich müssen Sie auch überprüfen, ob das __has_warning()
Makro vorhanden ist:
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
Sie könnten versucht sein, so etwas zu tun
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
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:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Dann kannst du Sachen wie machen
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
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:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Natürlich gibt es zwischen den Compilern keine große Übereinstimmung hinsichtlich der Syntax:
- GCC 4.6+:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
- klirren:
#pragma clang diagnostic push
/#pragma diagnostic pop
- Intel 13+ (und wahrscheinlich früher):
#pragma warning(push)
/#pragma warning(pop)
- MSVC 15+ (VS 9.0 / 2008):
#pragma warning(push)
/#pragma warning(pop)
- ARM 5.6+:
#pragma push
/#pragma pop
- TI 8.1+:
#pragma diag_push
/#pragma diag_pop
- Pelles C 2.90+ (und wahrscheinlich früher):
#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:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Ist ungefähr gleichbedeutend mit einmal vorverarbeitet zu
#pragma foo
Auf diese Weise können wir Makros erstellen, damit wir Code wie schreiben können
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
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:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
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.