Does There Exist a Static_Warning

Does there exist a static_warning?

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 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__)

The macro can be invoked at namespace, structure, and function scope. Given the input:

#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>;

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&)’
is deprecated (declared at static_warning.cpp:1): Failed with 1 and 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&)’
is deprecated (declared at static_warning.cpp:6): 2 and 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&)’
is deprecated (declared at static_warning.cpp:12): Not so good on 3 and 4 [-Wdeprecated-declarations]
static_warning.cpp: In constructor ‘wrap<T>::static_warning19::static_warning19() [with T = int]’:
static_warning.cpp:24:17: instantiated from here
static_warning.cpp:19:3: warning: ‘void wrap<T>::static_warning19::_(const detail::false_type&) [with T = int]’
is deprecated (declared at static_warning.cpp:19): Bad with 4 and 5 [-Wdeprecated-declarations]

While Visual C++ 2010 (at /W3 or above) says:


warnproj.cpp(1): warning C4996: 'static_warning1::_': Failed with 1 and 2
warnproj.cpp(1) : see declaration of 'static_warning1::_'
warnproj.cpp(6): warning C4996: 'Foo::static_warning6::_': 2 and 3: oops
warnproj.cpp(6) : see declaration of 'Foo::static_warning6::_'
warnproj.cpp(12): warning C4996: 'func::static_warning12::_': Not so good on 3 and 4
warnproj.cpp(12) : see declaration of 'func::static_warning12::_'
warnproj.cpp(19): warning C4996: 'wrap<T>::static_warning19::_': Bad with 4 and 5
with
[
T=int
]
warnproj.cpp(19) : see declaration of 'wrap<T>::static_warning19::_'
with
[
T=int
]
warnproj.cpp(19) : while compiling class template member function 'wrap<T>::static_warning19::static_warning19(void)'
with
[
T=int
]
warnproj.cpp(24) : see reference to class template instantiation 'wrap<T>::static_warning19' being compiled
with
[
T=int
]

Clang++ 3.1 on Linux produces the arguably nicer output (color not shown):


tst3.cpp:1:1: warning: '_' is deprecated: Failed with 1 and 2
[-Wdeprecated-declarations]
STATIC_WARNING(1==2, "Failed with 1 and 2");
^
tst3.cpp:24:38: note: expanded from macro 'STATIC_WARNING'
PP_CAT(static_warning,__LINE__)() {_(::detail::converter<(cond)>());} \
^
tst3.cpp:6:3: warning: '_' is deprecated: 2 and 3: oops
[-Wdeprecated-declarations]
STATIC_WARNING(2==3, "2 and 3: oops");
^
tst3.cpp:24:38: note: expanded from macro 'STATIC_WARNING'
PP_CAT(static_warning,__LINE__)() {_(::detail::converter<(cond)>());} \
^
tst3.cpp:12:3: warning: '_' is deprecated: Not so good on 3 and 4
[-Wdeprecated-declarations]
STATIC_WARNING(3==4, "Not so good on 3 and 4");
^
tst3.cpp:24:38: note: expanded from macro 'STATIC_WARNING'
PP_CAT(static_warning,__LINE__)() {_(::detail::converter<(cond)>());} \
^
tst3.cpp:19:3: warning: '_' is deprecated: Bad with 4 and 5
[-Wdeprecated-declarations]
STATIC_WARNING(4==5, "Bad with 4 and 5");
^
tst3.cpp:24:38: note: expanded from 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.

static_message or something like that

Would BOOST_STATIC_WARNING work for you?

Compiler warning when using a specific template specialization of a class

I could reuse the STATIC_WARNING_TEMPLATE from Does there exist a static_warning? proposed by in combination with boost::is_same to generate a warning when using a specific template parameter:

template<class T, class DisableWarning = void>
class Foo {
public:
STATIC_WARNING_TEMPLATE(FOO_WARNING,
(boost::is_same<DisableWarning, DislikedType>::value || !boost::is_same<T, DislikedType>::value),
"A warning")

With this solutions user can disable the warning when defining DisableWarning as the DislikedType.

Are methods with a method could be static warning considered bad form in JavaScript/TypeScript?

Code which does not interact with instance should be a free function or at least a static method of a class when you believe it is tightly coupled with class API.

Every additional method you add to API has to be supported. So larger classes require more support than smaller classes. In some languages, like Java, you can't have free function, so you have to attach function to some class, but TypeScript and JS are more flexible, so there is no need to pollute class API.

And you could consider it from the performance optimization point of view.

When JS evaluates class method it looks it up in the object instance, than in the object prototype, than in the parent's prototype, etc. Every lookup eats cpu time, so when you think about performance, free function is your choice.

Include #warning within a macro to be evaluated later?

Using the TODO Makro from the GCC online doc, here is what you want:

#define DO_PRAGMA(x) _Pragma (#x)
#define TODO(x) DO_PRAGMA(message ("TODO - " #x))
#ifdef SUPRESS_NOTES
# define BUILD_NOTE
#else
# define BUILD_NOTE DO_PRAGMA(message ("The blahblah hasn't been implemented " \
"yet; use foo to do so."))
#endif

Why is there no warning for useless conditional returns in C++?

Compiler warnings should maintain the balance between false positives and false negatives.

Too many warnings - and you'll spend a lot of your time walking through them without any actual improvement (or, more realistically, you will disable them altogether).

It is hard enough to imagine a situation where such a warning shows a real problem with the code, and not just a minor stylistic issue.

Consider, for example, -Wunused. It is pretty often indicates that you misspelled some variable name, or forgot this:

float x = ...;
float y = ...;

return atan2(y, y);
//x is never used, probably an error

Your example could be a diagnostic for a static analysis tool, but too minor to be useful as a general compiler warning.



Related Topics



Leave a reply



Submit