Search code examples
c++c++11gccvisual-c++clang

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.


Solution

  • 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.