47

Ich weiß, dass die # warning Direktive nicht C/C++ Standard ist, aber mehrere Compiler unterstützen es, einschließlich gcc/g ++. Aber für diejenigen, die es nicht unterstützen, werden sie es still ignorieren oder wird es zu einem Kompilierungsfehler führen? Mit anderen Worten, kann ich es sicher in meinem Projekt verwenden, ohne den Build für Compiler zu unterbrechen, die es nicht unterstützen?Portabilität von #warning Präprozessordirektive

Antwort

26

Wenn ein Compiler #warning nicht unterstützt, wird wahrscheinlich ein Fehler ausgegeben. Im Gegensatz zu Pragma gibt es keine Empfehlung, dass der Präprozessor ignorierte Anweisungen ignoriert.

Nachdem ich das gesagt habe, habe ich Compiler auf verschiedenen (einigermaßen gebräuchlichen) Plattformen verwendet und sie haben alle #warning unterstützt.

+3

Anscheinend hast du MS Visual Studio Professional 2015 nie probiert ;-). –

+1

@ PeterA.Schneider: Sicher hatte ich 2008 nicht! –

0

Tatsächlich ignorieren die meisten Compiler, die ich kenne, unbekannte #pragma-Direktiven und geben eine Warnmeldung aus - im schlimmsten Fall erhalten Sie also immer noch eine Warnung.

+4

#warning ist jedoch kein #pragma. –

+3

Aus irgendeinem Grund lese ich die Frage als "#pragma warning" –

3

Sie erhalten wahrscheinlich mindestens eine nicht erkannte Weigerung von Compilern, die #warning nicht erkennen, auch wenn der Codeblock nicht in Ihrer Kompilierung enthalten ist. Das könnte oder könnte nicht als ein Fehler behandelt werden - der Compiler könnte es legitimerweise als einen Fehler behandeln, aber viele wären laxer.

Kennen Sie einen anderen Compiler als GCC/G ++, der #warning bereitstellt? [Editiert: Sun Solaris 10 (Sparc) und das Studio 11 C/C++ Compiler akzeptieren beide #WARNING.]

1

Ich hatte dieses Problem einmal mit einem Compiler für einen Atmel-Prozessor. Und es erzeugte Präprozessorfehler aufgrund des unbekannten Warnungs-Tokens.

Leider schien die Lösung darin zu bestehen, den gesamten Quellbaum so zu konvertieren, dass er das #pragma-Äquivalent verwendet und akzeptiert, dass das Build-Verhalten bei Verwendung von gcc unterschiedlich sein würde.

68

Es sollte beachtet werden, dass MSVC die Syntax verwendet:

 
#pragma message ("your warning text here") 

Die übliche #WARNING Syntax erzeugt einen fatalen Fehler

 
C1021: invalid preprocessor command 'warning' 

so ist es auf diese Compiler nicht tragbar.

+21

Dies ist einer der seltenen Fälle, wenn MS die Dinge richtig macht. – doc

+0

Ist MSVC-Syntax tragbar? Ich meine, würde es richtig eine Warnung mit anderen Compilern erzeugen? –

+0

Habe gerade einen schnellen Check mit gcc-4.7.2 gemacht. [$ gcc -c -Werror file.c] ergibt [file.c: 10: 9: note: #pragma message: Foo bar baz] Also erzeugt es eine "Note", die nicht als Warnung behandelt wird (dh sie tut es nicht t den Build mit aktiviertem -Werror fehlschlagen. Aber es scheint richtig zu analysieren (wie alle #pragmas sein sollten), so dass es in diesem Sinne portabel ist. – nolandda

0

Wenn ich von Mingw zu Visual Studio wechselte, fügte ich solche Zeilen meinem globalen Konfigurationsheader hinzu. (Schließen Sie es in stdafx.h)

#ifdef __GNUC__ 
//from https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html 
//Instead of put such pragma in code: 
//#pragma GCC diagnostic ignored "-Wformat" 
//use: 
//PRAGMA_GCC(diagnostic ignored "-Wformat") 
#define DO_PRAGMA(x) _Pragma (#x) 
#define PRAGMA_GCC(x) DO_PRAGMA(GCC#x) 

#define PRAGMA_MESSAGE(x) DO_PRAGMA(message #x) 
#define PRAGMA_WARNING(x) DO_PRAGMA(warning #x) 
#endif //__GNUC__ 
#ifdef _MSC_VER 
/* 
#define PRAGMA_OPTIMIZE_OFF __pragma(optimize("", off)) 
// These two lines are equivalent 
#pragma optimize("", off) 
PRAGMA_OPTIMIZE_OFF 
*/ 
#define PRAGMA_GCC(x) 
// https://support2.microsoft.com/kb/155196?wa=wsignin1.0 
#define __STR2__(x) #x 
#define __STR1__(x) __STR2__(x) 
#define __PRAGMA_LOC__ __FILE__ "("__STR1__(__LINE__)") " 
#define PRAGMA_WARNING(x) __pragma(message(__PRAGMA_LOC__ ": warning: " #x)) 
#define PRAGMA_MESSAGE(x) __pragma(message(__PRAGMA_LOC__ ": message : " #x)) 

#endif 

//#pragma message "message quoted" 
//#pragma message message unquoted 

//#warning warning unquoted 
//#warning "warning quoted" 

PRAGMA_MESSAGE(PRAGMA_MESSAGE unquoted) 
PRAGMA_MESSAGE("PRAGMA_MESSAGE quoted") 

#warning "#pragma warning quoted" 

PRAGMA_WARNING(PRAGMA_WARNING unquoted) 
PRAGMA_WARNING("PRAGMA_WARNING quoted") 

Jetzt benutze ich PRAGMA_WARNING (dieser Bedarf festgelegt werden)

Leider gibt es keine #pragma warning in gcc, so dass er nicht näher bezeichnet Pragma warnt.

Ich bezweifle, dass gcc #pragma warning" eher als Microsoft hinzufügen #warning hinzufügen wird.