It is possible have code that works everywhere, and emits custom
warnings on many compilers, including most compilers people are likely
to use (GCC, clang, MSVC, Intel, ...).
First, we should distinguish between warnings and informational
messages. I think the only thing that makes sense is that, if you
compile with fatal warnings (e.g., -Werror
on GCC), warnings
should cause compilation to fail, whereas informational messages
shouldn't.
As the original question mentions, MSVC 9.0+ supports
#pragma message("Hello")
Despite the (IMHO unfortunate) name, MSVC will emit a warinng here,
not an informational message. AFAICT there is no way to emit an
informational message.
GCC 4.8+ and Intel support warning message pragmas, which means we can
use the preprocessor to generate them:
#pragma GCC warning "Hello"
Note that, as of version 18, PGI does not support such warnings, even
though pgc++ masquerades as a version of GCC that should (i.e., it
sets __GNUC__
, __GNUC_MINOR__
, and __GNUC_PATCHLEVEL__
to values which
indicate GCC >= 4.8). They are
aware
of the issue. To get around this while still allowing some future
version of PGI which does support those to work properly, you can do
something like:
#if defined(__PGI)
# pragma diag_suppress 1675
#endif
Unfortunately I don't think there is a way to push/pop the warning
stack for PGI, so if you do this all subsequent unknown pragmas will
be silently ignored. Also, keep in mind that #pragma message
is
silently ignored by PGI (it will not even generate a warning about the
pragma being unknown).
Clang also supports #pragma GCC warning
(as well as #pragma clang
...
), but as of 6.0 such warnings are actually informational (I've
filed a bug). I'm not sure when support was added, but clang's version
numbers are pretty useless anyways (thanks to Apple setting them to
something completely different in their clang
distribution). Unfortunately there is no __has_pragma
feature test
macro, but we can temporarily disable the unknown pragma warnings so
that if the compiler doesn't support the pragma it will be silently
ignored 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 ugly, but at least we can hide it behind a macro.
Cray 5.0+ also has a pragma for messages:
#pragma _CRI message "Hello"
I don't actually have access to Cray's compiler, so I can't be sure
about whether it is informational or a warning. If someone knows the
anwser, please comment!
Putting it all together, I recently added some macros to
Hedley to handle this, the current
version 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 Hedley (it's a single public domain / CC0 header for just this sort of thing) you can replace the internal macros without too much effort. If you do that, I'd suggest basing your port on the Hedley repo instead of this answer as I'm much more likely to keep it up to date.