11

In C# we can use #warning to show a warning in error window.
In Visual C++, #pragma message is something like that, but it just a outputs a message not a warning.

In C++ (Windows, Visual Studio, MSVC) is there a way to show a warning to user purposely?

I tried #warning DEBUG is defined which works in some other compilers, but not MSVC.
It gives me this error:

error C1021: invalid preprocessor command 'warning' AecProject stdafx.h 49

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147
  • James McNellis provides an excellent solution for warnings in MSVC here, piggybacking off of `#pragma message` and matching the compiler's internal standardized format for warnings: http://stackoverflow.com/a/2706693/366904 – Cody Gray - on strike Jul 05 '16 at 11:59

2 Answers2

9

In gcc, #warning works fine in the way that you would expect (i.e. like #error it outputs a message at compile time, but does not cause the compilation to terminate)

It seems that #warning is not available in Visual Studio. Instead you can try experimenting with #pragma warning although this does not emit a message but allows the settings for compiler messages to be altered. The syntax for this is more complex and can be found here

Component 10
  • 10,247
  • 7
  • 47
  • 64
  • Hi, I am getting this but the error is coming from boost/pending/relaxed_heap.hpp, and that library is being used internally I know this wasn't the question you answered but let me know if you have an answer. – anand_v.singh Feb 13 '20 at 05:48
0

I have a hacky solution that works under some conditions with a C++-14 compiler.

With C++-14 compilers that support [[deprecated("...")]], this (somewhat hacky solution) works for MSVC but also for mingw, g++, and clang:

[[deprecated("read the argument to emit_warning")]]
inline int emit_warning(char const*)
{
    return 0;
}
static auto w1 = emit_warning("message1");
static auto w2 = emit_warning("message2");

int main()
{
    return 0;
}

It has the advantage over #pragma message in that it actually emits a warning, which means that /WX will convert this warning to an error just like any other, and other MSVC flags can be used to turn it off, though the warning that is emitted is C4996, which is use of a deprecated function.

I played around with putting this in a macro, but the warning gets a lot more complex and hides the real issue, which is this warning message. So, while this is a bit hacky, it at least generates a proper warning.

Output with g++ (Linux):

./test1.cc:6:41: warning: ‘int emit_warning(const char*)’ is deprecated: read the argument to emit_warning [-Wdeprecated-declarations]
    6 | static auto w1 = emit_warning("message1");
      |                                         ^
./test1.cc:2:12: note: declared here
    2 | inline int emit_warning(char const*)
      |            ^~~~~~~~~~~~
./test1.cc:6:41: warning: ‘int emit_warning(const char*)’ is deprecated: read the argument to emit_warning [-Wdeprecated-declarations]
    6 | static auto w1 = emit_warning("message1");
      |                                         ^
./test1.cc:2:12: note: declared here
    2 | inline int emit_warning(char const*)
      |            ^~~~~~~~~~~~
./test1.cc:7:41: warning: ‘int emit_warning(const char*)’ is deprecated: read the argument to emit_warning [-Wdeprecated-declarations]
    7 | static auto w2 = emit_warning("message2");
      |                                         ^
./test1.cc:2:12: note: declared here
    2 | inline int emit_warning(char const*)
      |            ^~~~~~~~~~~~
./test1.cc:7:41: warning: ‘int emit_warning(const char*)’ is deprecated: read the argument to emit_warning [-Wdeprecated-declarations]
    7 | static auto w2 = emit_warning("message2");
      |                                         ^
./test1.cc:2:12: note: declared here
    2 | inline int emit_warning(char const*)
      |            ^~~~~~~~~~~~

Output with MSVC:

cl -nologo -O2 -Zi -Gy -EHsc -MD -TP -GR  -W3 -w14996   -c ./test1.cc -Fo./build/test1.obj
test1.cc
./test1.cc(6): warning C4996: 'emit_warning': read the argument to emit_warning
./test1.cc(7): warning C4996: 'emit_warning': read the argument to emit_warning

Unfortunately

  • With MSVC, the output doesn't include the actual call, so it's a bit clumsy...I suppose you could create a separate deprecated function for each warning whose name communicates information, but that's even more hacky.
  • Warning 4996 is a level 3 warning by default, so you need either /W3 or /W14996 to even see the warning.