I'm aware of this question which mentions Boost's "STATIC WARNING", but I'd like to ask again, specifically, how I could implement a static_warning
which operates similarly to static_assert
but only emits a warning at compile time rather than an aborting compilation error.
I'd like something similar to Alexandrescu's proposal for a static assert in pre-C++11 days which somehow managed to print some useful contextual information as part of the error.
It would be acceptable to require that the user enable certain standard compiler warnings in order for this construction to work (perhaps "invalid pointer conversion" or "breaks strict aliasing rules") -- any warning that should be part of a normal compilation anyway can be used.
In short, I want static_warning(false, "Hello world");
to create a compiler warning that should somehow include the string "hello world" in the warning message. Is this possible, say in GCC and MSVC, and how?
I'd happily give out a small reward bounty for any particularly clever solution.
As a bit of explanation: I got the idea when thinking about this question: A static warning would be a useful way to trace through the compile-time process of complex template specializations, which are otherwise fairly hard to debug. A static warning could be used as a simple beacon for the compiler to emit "I'm now compiling this part of the code."
Update. Ideally, the warning would be triggered in the following setup:
template <typename T> struct Foo
{
static_warning(std::is_pointer<T>::value, "Attempting to use pointer type.");
// ...
};
int main() { Foo<int> a; Foo<int*> b; }
Playing off of Michael E's comment:
The macro can be invoked at namespace, structure, and function scope. Given the input:
GCC 4.6 (at default warning level) produces:
While Visual C++ 2010 (at /W3 or above) says:
Clang++ 3.1 on Linux produces the arguably nicer output (color not shown):
Here's the best I've come up with so far. It's basic and doesn't quite fit your requirements, but instead goes the route of
BOOST_MPL_ASSERT_MSG
in that your message has to take the form of a valid identifier. (As far as I know, the only way you could get a string printed in the warning message is if the warning you used happened to also be one to do with strings, and printed its contents.)It requires the warning for an unused variable be enabled. In g++ this is
-Wunused-variable
(enabled by-Wall
), and in MSVC it's warning C4101 which is enabled at Warning Level 3.It's obviously not very tested and could be enhanced in a few ways (use
__COUNTER__
instead of__LINE__
on supported compilers, prettier message printing, use Boost to simplify, etc.), but seems to get the job done. Here's the boiler-plate:And a test:
In MSVC this produces:
And in GCC it produces:
Here is a solution that uses the Boost MPL library:
It comes with the same restriction as GMan's solution: the message must be a valid identifier. Here are two tests
and
With MSVS 2010 the first test compiles without warnings, the second compiles with the warning
The code uses boost::mpl::print. From the book C++ Template Metaprogramming by D. Abrahams and A. Gurtovoy, page 171:
To generate a compile-time execution log, we'd need a way to generate a diagnostic message - a warning. Because there's no single construct that will cause all compilers to generate a warning (indeed, most compilers let you disable warnings altogether), MPL has a
print
metafunction that is just likeidentity
except that it is tuned to generate a warning on a variety of popular compilers with their usual settings.