Bri Bri
Bri Bri

Reputation: 2288

With C++11, how can I generate a warning message in a manner that works in gcc, clang, and MSVC?

When compiling C++11 using clang or gcc, I can generate a warning message at compilation time using:

#warning My message here

This doesn't work on Windows when I use MSVC, though. How can I intentionally generate a warning message that will work regardless of C++ compiler?

This question is not a duplicate of "preprocessor #warning equivalent in Visual C++?" because that question is not attempting to answer the question of how do it in a way that works across compilers.

Upvotes: 0

Views: 527

Answers (2)

s7a19t4r
s7a19t4r

Reputation: 126

#warning is not a standard C99 feature (because some compilers only support C99, and some programs may not be compiled with C++11 and later standard libraries), so it cannot be used on compilers that do not support it. You can use #ifdef to check the defined compiler and change the directive based on the compiler. Easiest (but not the best) solution:

#ifdef _MSC_VER  // if MSVC is the compiler
#    pragma NOTE(warning: warning here)
#else            // implied GCC or CLang
#    warning(warning here)
#endif

MSVC uses #pragma instead of #warning

Upvotes: 0

Bri Bri
Bri Bri

Reputation: 2288

Using this answer as a starting point, I found a method that works in gcc, clang, and MSVC. The following precompiler magic will do the trick:

#define EMIT_COMPILER_WARNING_STRINGIFY0(x) #x
#define EMIT_COMPILER_WARNING_STRINGIFY1(x) EMIT_COMPILER_WARNING_STRINGIFY0(x)
#ifdef __GNUC__
    #define EMIT_COMPILER_WARNING_COMPOSE(x) GCC warning x
#else
    #define EMIT_COMPILER_MESSAGE_PREFACE(type) \
    __FILE__ "(" EMIT_COMPILER_WARNING_STRINGIFY1(__LINE__) "): " type ": "
    #define EMIT_COMPILER_WARNING_COMPOSE(x) message(EMIT_COMPILER_MESSAGE_PREFACE("warning C0000") x)
#endif
#define WARNING(x) _Pragma(EMIT_COMPILER_WARNING_STRINGIFY1(EMIT_COMPILER_WARNING_COMPOSE(x)))

You can trigger a warning with:

WARNING("This is a warning message.")

In the case of MSVC, it displays a compiler message in the same format that the compiler would for a warning message, which causes it to be detected as a warning. (The use of C0000 is simply to stick to that format. C0000 is not actually a valid warning message number in MSVC.)

In the case of GCC / clang, it's simply using the supported pragma for displaying a warning message using _Pragma() instead of #pragma or #warning.

Upvotes: 3

Related Questions