views:

892

answers:

3

In MSVC I have this in a header:

#define STR(x)          #x
#define STR2(x)         STR(x)
#define NOTE(text)      message (__FILE__ "(" STR2(__LINE__) ") : -NOTE- " #text)
#define noteMacro(text) message (__FILE__ "(" STR2(__LINE__) ") : " STR2(text))

and I do

#pragma NOTE(my warning here)

GCC has:

#warning(my warning here)

However MSVC (2003) throws a fit when it sees #warning and gives "fatal error C1021: invalid preprocessor command 'warning'"

What can I do about this? Is there a way to have GCC recognize MSVC warnings or MSVC not throw an error on GCC warnings? Is there something I can do that works on both? I can have GCC warn me about unknown pragmas but that's not the most ideal solution.

+4  A: 

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

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

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

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

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

See also: Portability of #warning preprocessor directive

Jonathan Leffler
+1  A: 

Guard them with #if statements. Look for a symbol that's defined by one compiler 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 see another way.

Mark Ransom
You added this while I was off editing my answer and adding the inverse test ... I guess _MSC_VER is the counterpart of __GNUC__! Thanks.
Jonathan Leffler
_MSC_VER not only declares you to be in Microsoft C++, it also defines which version you're using.
Mark Ransom
+5  A: 

The best solution I've found for this problem 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 use

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

throughout the code instead of #warning

Under MSVC you'll get a message like this:

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

Under gcc you'll get:

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

Not perfect, but a reasonable compromise.

Paul Ryland