[ACCEPTED]-user warnings on msvc AND gcc?-user-warning

Accepted answer
Score: 15

The best solution I've found for this problem 5 is to have the following in a common header:

// compiler_warning.h
#define STRINGISE_IMPL(x) #x
#define STRINGISE(x) STRINGISE_IMPL(x)

// Use: #pragma message WARN("My message")
#if _MSC_VER
#   define FILE_LINE_LINK __FILE__ "(" STRINGISE(__LINE__) ") : "
#   define WARN(exp) (FILE_LINE_LINK "WARNING: " exp)
#else//__GNUC__ - may need other defines for different compilers
#   define WARN(exp) ("WARNING: " exp)
#endif

Then 4 use

#pragma message WARN("your warning message here")

throughout the code instead of #warning

Under 3 MSVC you'll get a message like this:

c:\programming\some_file.cpp(3) : WARNING: your warning message here

Under 2 gcc you'll get:

c:\programming\some_file.cpp:25: note: #pragma message: WARNING: your warning message here

Not perfect, but a reasonable 1 compromise.

Score: 6

As you have now discovered, #warning is not a standard 17 feature, so you cannot use it with compilers 16 that don't suppport it. If you want your 15 code to work across platforms, you won't 14 use #warning at all - or, at the least, not in code 13 that MSVC is intended to process (it could 12 be preprocessed out by #ifdef or equivalent). Hence:

#ifdef __GNUC__
#warning(warning message)
#else
#pragma NOTE(warning message)
#endif

But 11 that repeats the message and I'm sure you 10 had in mind not doing that - and it is bulky 9 ; you'd only use it very seldom. You might 8 also need to deal with other compilers than 7 GCC (and I'm not familiar enough with MSVC 6 to know how to identify it reliably).

It 5 would be nice if #warning were standardized; it 4 is not standardized in C99.

(There was, once 3 upon a long time ago, an SO question about 2 such features that could be added to C and 1 #warning came up there.)

See also: Portability of #warning preprocessor directive

Score: 3

Guard them with #if statements. Look for 3 a symbol that's defined by one compiler 2 but not the other.

#ifdef _MSC_VER
#pragma NOTE(my warning here)
#else
#warning(my warning here)
#endif

Kind of ugly, but I don't 1 see another way.

Score: 2

It is possible have code that works everywhere, and 57 emits custom warnings on many compilers, including 56 most compilers people are likely to use 55 (GCC, clang, MSVC, Intel, ...).

First, we 54 should distinguish between warnings and 53 informational messages. I think the only 52 thing that makes sense is that, if you compile 51 with fatal warnings (e.g., -Werror on GCC), warnings should 50 cause compilation to fail, whereas informational 49 messages shouldn't.

As the original question 48 mentions, MSVC 9.0+ supports

#pragma message("Hello")

Despite the 47 (IMHO unfortunate) name, MSVC will emit 46 a warinng here, not an informational message. AFAICT 45 there is no way to emit an informational 44 message.

GCC 4.8+ and Intel support warning 43 message pragmas, which means we can use 42 the preprocessor to generate them:

#pragma GCC warning "Hello"

Note that, as 41 of version 18, PGI does not support such 40 warnings, even though pgc++ masquerades 39 as a version of GCC that should (i.e., it sets 38 __GNUC__, __GNUC_MINOR__, and __GNUC_PATCHLEVEL__ to values which indicate GCC >= 4.8). They 37 are aware of the issue. To get around this while 36 still allowing some future version of PGI 35 which does support those to work properly, you 34 can do something like:

#if defined(__PGI)
#  pragma diag_suppress 1675
#endif

Unfortunately I don't 33 think there is a way to push/pop the warning stack 32 for PGI, so if you do this all subsequent 31 unknown pragmas will be silently ignored. Also, keep 30 in mind that #pragma message is silently ignored by PGI 29 (it will not even generate a warning about 28 the pragma being unknown).

Clang also supports 27 #pragma GCC warning (as well as #pragma clang ...), but as of 6.0 such warnings 26 are actually informational (I've filed a 25 bug). I'm not sure when support was added, but 24 clang's version numbers are pretty useless 23 anyways (thanks to Apple setting them to something 22 completely different in their clang distribution). Unfortunately 21 there is no __has_pragma feature test macro, but we 20 can temporarily disable the unknown pragma 19 warnings so that if the compiler doesn't 18 support the pragma it will be silently ignored 17 instead of emitting an unwanted warning:

#if defined(__has_warning)
#  if __has_warning("-Wunknown-pragmas")
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wunknown-pragmas"
#    pragma message "Hello"
#    pragma clang warning "Hello"
#    pragma clang diagnostic pop
#  endif
#endif

Sure, it's 16 ugly, but at least we can hide it behind 15 a macro.

Cray 5.0+ also has a pragma for 14 messages:

#pragma _CRI message "Hello"

I don't actually have access to 13 Cray's compiler, so I can't be sure about 12 whether it is informational or a warning. If 11 someone knows the anwser, please comment!

Putting 10 it all together, I recently added some macros 9 to Hedley to handle this, the current version 8 looks like this:

#if HEDLEY_HAS_WARNING("-Wunknown-pragmas")
#  define HEDLEY_MESSAGE(msg) \
  HEDLEY_DIAGNOSTIC_PUSH \
  _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
  HEDLEY_PRAGMA(message msg) \
  HEDLEY_DIAGNOSTIC_POP
#elif \
  HEDLEY_GNUC_VERSION_CHECK(4,4,0) || \
  HEDLEY_INTEL_VERSION_CHECK(16,0,0)
#  define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(message msg)
#elif HEDLEY_CRAY_VERSION_CHECK(5,0,0)
#  DEFINE HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(_CRI message msg)
#else
#  define HEDLEY_MESSAGE(msg)
#endif

#if HEDLEY_HAS_WARNING("-Wunknown-pragmas")
#  define HEDLEY_WARNING(msg) \
  HEDLEY_DIAGNOSTIC_PUSH \
  _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
  HEDLEY_PRAGMA(clang warning msg) \
  HEDLEY_DIAGNOSTIC_POP
#elif \
  (HEDLEY_GNUC_VERSION_CHECK(4,8,0) && !defined(__PGI)) || \
  HEDLEY_INTEL_VERSION_CHECK(16,0,0)
#  define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(GCC warning msg)
#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0)
#  define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(message(msg))
#else
#  define HEDLEY_WARNING(msg) HEDLEY_MESSAGE(msg)
#endif

If you don't want to use 7 Hedley (it's a single public domain / CC0 6 header for just this sort of thing) you 5 can replace the internal macros without 4 too much effort. If you do that, I'd suggest 3 basing your port on the Hedley repo instead 2 of this answer as I'm much more likely to 1 keep it up to date.

Score: 1

If you wish, you can add to the above solutions 8 a little thing (#pragma warning) before your #pragma message:

#pragma warning()
#pragma message(" SOME USER WARNING - FILE LINE etc... ")

This little 7 add-in generates real warning, and does 6 not look bad in the window of VC. For example:

1>e:\proj\file.h(19) : warning C4615: #pragma warning : unknown user warning type
1> SOME USER WARNING - FILE LINE etc...
1>proj - 0 error(s), 1 warning(s)

Usually 5 I use this method to warnings were not too 4 quiet, as in the case code without the #pragma warning().

For 3 example, the form of warnings too quiet 2 (for me of course).

1> SOME USER WARNING - FILE LINE etc..
1>proj - 0 error(s), 0 warning(s)

However, only a small 1 cosmetics.

More Related questions