c++ - Does there exist a static_warning? -
i'm aware of this question mentions boost's "static warning", i'd ask again, specifically, how implement static_warning
operates static_assert
emits warning @ compile time rather aborting compilation error.
i'd similar alexandrescu's proposal static assert in pre-c++11 days somehow managed print useful contextual information part of error.
it acceptable require user enable standard compiler warnings in order construction work (perhaps "invalid pointer conversion" or "breaks strict aliasing rules") -- warning should part of normal compilation anyway can used.
in short, want static_warning(false, "hello world");
create compiler warning should somehow include string "hello world" in warning message. possible, in gcc , msvc, , how?
i'd happily give out small reward bounty particularly clever solution.
as bit of explanation: got idea when thinking this question: static warning useful way trace through compile-time process of complex template specializations, otherwise hard debug. static warning used simple beacon compiler emit "i'm compiling part of code."
update. ideally, warning triggered in following setup:
template <typename t> struct foo { static_warning(std::is_pointer<t>::value, "attempting use pointer type."); // ... }; int main() { foo<int> a; foo<int*> b; }
playing off of michael e's comment:
#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 compiler 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 meaning of program in small way. // introduces member/variable declaration. means @ least 1 byte of space // in each structure/class instantiation. static_warning should preferred in // non-template situation. // 'token' must program-wide unique identifier. #define static_warning_template(token, cond, msg) \ static_warning(cond, msg) pp_cat(pp_cat(_localvar_, token),__line__)
the macro can invoked @ namespace, structure, , function scope. given input:
#line 1 static_warning(1==2, "failed 1 , 2"); static_warning(1<2, "succeeded 1 , 2"); struct foo { static_warning(2==3, "2 , 3: oops"); static_warning(2<3, "2 , 3 worked"); }; void func() { static_warning(3==4, "not on 3 , 4"); static_warning(3<4, "3 , 4, check"); } template <typename t> struct wrap { typedef t type; static_warning(4==5, "bad 4 , 5"); static_warning(4<5, "good on 4 , 5"); static_warning_template(wrap_warning1, 4==5, "a template warning"); }; template struct wrap<int>;
gcc 4.6 (at default warning level) produces:
static_warning.cpp: in constructor ‘static_warning1::static_warning1()’: static_warning.cpp:1:1: warning: ‘void static_warning1::_(const detail::false_type&)’ deprecated (declared @ static_warning.cpp:1): failed 1 , 2 [-wdeprecated-declarations] static_warning.cpp: in constructor ‘foo::static_warning6::static_warning6()’: static_warning.cpp:6:3: warning: ‘void foo::static_warning6::_(const detail::false_type&)’ deprecated (declared @ static_warning.cpp:6): 2 , 3: oops [-wdeprecated-declarations] static_warning.cpp: in constructor ‘func()::static_warning12::static_warning12()’: static_warning.cpp:12:3: warning: ‘void func()::static_warning12::_(const detail::false_type&)’ deprecated (declared @ static_warning.cpp:12): not on 3 , 4 [-wdeprecated-declarations] static_warning.cpp: in constructor ‘wrap<t>::static_warning19::static_warning19() [with t = int]’: static_warning.cpp:24:17: instantiated here static_warning.cpp:19:3: warning: ‘void wrap<t>::static_warning19::_(const detail::false_type&) [with t = int]’ deprecated (declared @ static_warning.cpp:19): bad 4 , 5 [-wdeprecated-declarations]
while visual c++ 2010 (at /w3 or above) says:
warnproj.cpp(1): warning c4996: 'static_warning1::_': failed 1 , 2 warnproj.cpp(1) : see declaration of 'static_warning1::_' warnproj.cpp(6): warning c4996: 'foo::static_warning6::_': 2 , 3: oops warnproj.cpp(6) : see declaration of 'foo::static_warning6::_' warnproj.cpp(12): warning c4996: 'func::static_warning12::_': not on 3 , 4 warnproj.cpp(12) : see declaration of 'func::static_warning12::_' warnproj.cpp(19): warning c4996: 'wrap<t>::static_warning19::_': bad 4 , 5 [ t=int ] warnproj.cpp(19) : see declaration of 'wrap<t>::static_warning19::_' [ t=int ] warnproj.cpp(19) : while compiling class template member function 'wrap<t>::static_warning19::static_warning19(void)' [ t=int ] warnproj.cpp(24) : see reference class template instantiation 'wrap<t>::static_warning19' being compiled [ t=int ]
clang++ 3.1 on linux produces arguably nicer output (color not shown):
tst3.cpp:1:1: warning: '_' deprecated: failed 1 , 2 [-wdeprecated-declarations] static_warning(1==2, "failed 1 , 2"); ^ tst3.cpp:24:38: note: expanded macro 'static_warning' pp_cat(static_warning,__line__)() {_(::detail::converter<(cond)>());} \ ^ tst3.cpp:6:3: warning: '_' deprecated: 2 , 3: oops [-wdeprecated-declarations] static_warning(2==3, "2 , 3: oops"); ^ tst3.cpp:24:38: note: expanded macro 'static_warning' pp_cat(static_warning,__line__)() {_(::detail::converter<(cond)>());} \ ^ tst3.cpp:12:3: warning: '_' deprecated: not on 3 , 4 [-wdeprecated-declarations] static_warning(3==4, "not on 3 , 4"); ^ tst3.cpp:24:38: note: expanded macro 'static_warning' pp_cat(static_warning,__line__)() {_(::detail::converter<(cond)>());} \ ^ tst3.cpp:19:3: warning: '_' deprecated: bad 4 , 5 [-wdeprecated-declarations] static_warning(4==5, "bad 4 , 5"); ^ tst3.cpp:24:38: note: expanded macro 'static_warning' pp_cat(static_warning,__line__)() {_(::detail::converter<(cond)>());} \ ^ tst3.cpp:23:17: note: in instantiation of member function 'wrap<int>::static_warning19::static_warning19' requested here template struct wrap<int> ^ 4 warnings generated.
Comments
Post a Comment