This question seeks to determine if a mechanism exists to implement a static warning akin to static_assert, but instead of halting compilation, it triggers a warning message during compilation.
Utilizing insights provided by a comment from Michael E, the following implementation is proposed:
<code class="c++">#if defined(__GNUC__) #define DEPRECATE(foo, msg) foo __attribute__((deprecated(msg))) #elif defined(_MSC_VER) #define DEPRECATE(foo, msg) __declspec(deprecated(msg)) foo #else #error This compiler is not supported #endif #define PP_CAT(x,y) PP_CAT1(x,y) #define PP_CAT1(x,y) x##y namespace detail { struct true_type {}; struct false_type {}; template <int test> struct converter : public true_type {}; template <> struct converter<0> : public false_type {}; } #define STATIC_WARNING(cond, msg) \ struct PP_CAT(static_warning,__LINE__) { \ DEPRECATE(void _(::detail::false_type const& ),msg) {}; \ void _(::detail::true_type const& ) {}; \ PP_CAT(static_warning,__LINE__)() {_(::detail::converter<(cond)>());} \ } // Note: using STATIC_WARNING_TEMPLATE changes the meaning of a program in a small way. // It introduces a member/variable declaration. This means at least one byte of space // in each structure/class instantiation. STATIC_WARNING should be preferred in any // non-template situation. // 'token' must be a program-wide unique identifier. #define STATIC_WARNING_TEMPLATE(token, cond, msg) \ STATIC_WARNING(cond, msg) PP_CAT(PP_CAT(_localvar_, token),__LINE__)</code>
The macro can be invoked at multiple scopes, including namespace, structure, and function. Here's an example:
<code class="c++">#line 1 STATIC_WARNING(1==2, "Failed with 1 and 2"); STATIC_WARNING(1<2, "Succeeded with 1 and 2"); struct Foo { STATIC_WARNING(2==3, "2 and 3: oops"); STATIC_WARNING(2<3, "2 and 3 worked"); }; void func() { STATIC_WARNING(3==4, "Not so good on 3 and 4"); STATIC_WARNING(3<4, "3 and 4, check"); } template <typename T> struct wrap { typedef T type; STATIC_WARNING(4==5, "Bad with 4 and 5"); STATIC_WARNING(4<5, "Good on 4 and 5"); STATIC_WARNING_TEMPLATE(WRAP_WARNING1, 4==5, "A template warning"); }; template struct wrap<int>;</code>
With appropriate compiler warnings enabled, the provided implementation produces warning messages at compile time, conveying the specified message:
GCC 4.6:
static_warning1::_: Failed with 1 and 2 Foo::static_warning6::_: 2 and 3: oops func()::static_warning12::_: Not so good on 3 and 4 wrap<T>::static_warning19::_: Bad with 4 and 5
Visual C 2010:
'static_warning1::_': Failed with 1 and 2 'Foo::static_warning6::_': 2 and 3: oops 'func::static_warning12::_': Not so good on 3 and 4 'wrap<T>::static_warning19::_': Bad with 4 and 5
Clang 3.1:
'_' is deprecated: Failed with 1 and 2 '_' is deprecated: 2 and 3: oops '_' is deprecated: Not so good on 3 and 4 '_' is deprecated: Bad with 4 and 5
The above is the detailed content of Is there a static warning equivalent to `static_assert` that produces a warning instead of halting compilation?. For more information, please follow other related articles on the PHP Chinese website!