64

I know that the #warning directive is not standard C/C++, but several compilers support it, including gcc/g++. But for those that don't support it, will they silently ignore it or will it result in a compile failure? In other words, can I safely use it in my project without breaking the build for compilers that don't support it?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jonner
  • 6,331
  • 6
  • 30
  • 28

6 Answers6

87

It should be noted that MSVC uses the syntax:

#pragma message ( "your warning text here" )

The usual #warning syntax generates a fatal error

C1021: invalid preprocessor command 'warning'

so it is not portable to those compilers.

nolandda
  • 2,254
  • 3
  • 17
  • 19
  • 28
    This is one of the rare cases, when MS does things in the right way. – mip Aug 05 '10 at 14:05
  • 1
    Is MSVC syntax portable? I mean, would it properly generate a warning with other compilers? – aka.nice Jun 11 '13 at 13:34
  • 2
    Just ran a quick check using gcc-4.7.2. [$ gcc -c -Werror file.c] yields [file.c:10:9: note: #pragma message: Foo bar baz] So it produces a "note" that is not treated as a warning (i.e. It doesn't fail the build with -Werror enabled). But it appears parse correctly (as all #pragmas should be) so it is portable in that sense. – nolandda Jun 14 '13 at 20:16
  • 6
    In MSVC 2008 `#pragma message` does not generate a warning too - it just outputs text to the Build Log. As result, f.i. it is not displayed in `Error List` window, nor increments the total number of warnings. – nevermind Jul 08 '13 at 17:12
  • 11
    if you place 'warning' in the message then it still counts as a warning, e.g. #pragma message( "warning: foo" ) – jheriko Nov 06 '13 at 17:07
  • 3
    fwiw, this syntax works with openwatcom too. (yeah I bumped an old thread. People are going to google stuff like this forever) – JustJeff Mar 27 '15 at 20:02
  • 1
    @JustJeff, no worries, SO is a more enlightened place than those old, dust-covered forums where they like it that way (being covered with dust forever, once it has settled). Here you actually get a reward (a badge?) for extending an old post. – Sz. Nov 25 '15 at 22:09
  • @doc It's _not_ the right way when it deviates from the _de facto_ norm. – K3---rnc Oct 20 '17 at 20:32
31

It is likely that if a compiler doesn't support #warning, then it will issue an error. Unlike #pragma, there is no recommendation that the preprocessor ignore directives it doesn't understand.

Having said that, I've used compilers on various different (reasonably common) platforms and they have all supported #warning.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
3

You are likely to get at least an unrecognized directive warning from compilers that don't recognize #warning, even if the code block is not included in your compilation. That might or might not be treated as an error - the compiler could legitimately treat it as an error, but many would be more lax.

Are you aware of (can you name) a compiler other than GCC/G++ that provides #warning? [Edited: Sun Solaris 10 (Sparc) and the Studio 11 C/C++ compilers both accept #warning.]

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
3

When switching from mingw to visual studio, I added such lines to my global config header. (include it 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")

Now I use PRAGMA_WARNING(this need to be fixed)

Sadly there is no #pragma warning in gcc, so it warns unspecified pragma.

I doubt that gcc will add #pragma warning" rather than microsoft adding #warning.

Fantastory
  • 1,891
  • 21
  • 25
1

I had this problem once with a compiler for an Atmel processor. And it did generate preprocessor errors due to the unknown #warning token.

Unfortunately the solution seemed to be to convert the whole source tree to use the #pragma equivalent and accept that the build behavior was going to differ if using gcc.

Andrew Edgecombe
  • 39,594
  • 3
  • 35
  • 61
0

Actually most compilers that I know about ignore unknown #pragma directives, and output a warning message - so in the worst case, you'll still get a warning.

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239