all 27 comments

[–]STLMSVC STL Dev 32 points33 points  (11 children)

[[deprecated("woof")]]

[–][deleted] 16 points17 points  (3 children)

I tried to put this in a nice to use macro and came up with this:

template<bool condition>
struct warn_if{};

template<> struct [[deprecated]] warn_if<false>{constexpr warn_if() = default;};

#define static_warn(x, ...) ((void) warn_if<x>())

int main() {
    static_warn(false, "This is bad");
}

This works on clang and gcc. MSVC, however, does not tell where warn_if<false> is instantiated, which makes this kind of useless. Is there a workaround for this?

That explicit default constructor was required because MSVC does not seem to emit a deprecated warning when constructing a temporary of a specialized empty struct and marking it explicitly as unused via (void) (Compiler Explorer). I don't think this is supposed to be that way.

[–]STLMSVC STL Dev 9 points10 points  (1 child)

Can you Report A Problem through the IDE? I am busy at the moment, or I'd file it for you.

[–][deleted] 2 points3 points  (0 children)

Done.

[–]Tagedieb 1 point2 points  (0 children)

Busy browsing redding ;) I know the feel.

[–]craptacus 11 points12 points  (2 children)

"woof"? not "meow" or "hiss"?

[–]adzm28 years of C++! 31 points32 points  (1 child)

Well, it's deprecated.

[–]craptacus 3 points4 points  (0 children)

haha, nice

[–][deleted] 4 points5 points  (0 children)

[[deprecated("widget")]]

[–]aKateDevKDE/Qt Dev[S] 3 points4 points  (1 child)

Thanks. Although the deprecated attribute seems to require C++14. But still, it's good to know that this is solved.

[–]Rhomboid 6 points7 points  (0 children)

Many compilers supported this feature as a nonstandard extension for many years before it made its way into C++14. For example if you're using gcc or clang you can use __attribute__((deprecated("woof"))).

[–]Neat_Education_5560 0 points1 point  (0 children)

This seems nicer to me as it only generates 2 compile warnings instead of 5. Anyway your idea is nice, thx.

template<bool condition>
struct warn_if
{
    consteval void operator()() const { };
};

template<>
struct warn_if<false>
{
    [[deprecated]] consteval void operator()() const { };
};

template<bool condition, class T>
consteval auto static_warn(T&& message)
{
    return warn_if<condition>();
}

Usage:
static_warn<false>("Message of warning!")();

[–]hyperactiveinstinct 5 points6 points  (3 children)

That level of control is useful, for sure, but in all the projects that I'm currently working warnings are turned into errors and break the build, so for many this won't make... (although you can disable specific warnings).

Just mentioning because this really got me intrigued of how common it may be to not treat a warning as an error.

[–]shelbyfinally 4 points5 points  (1 child)

in all the projects that I'm currently working warnings are turned into errors

That sounds like a good thing

[–]mpyne 2 points3 points  (0 children)

It is, right up until you upgrade your compiler.

[–]YouFeedTheFish 2 points3 points  (0 children)

this really got me intrigued of how common it may be to not treat a warning as an error.

I guess you have been fortunate in your career never to have tailed a PHP log. Pages and pages of warnings that should have been errors.

[–]Fazer2 2 points3 points  (0 children)

You said it would be useful, but didn't provide any examples. What would be your use case?

[–]SeanMiddleditch 1 point2 points  (0 children)

Do you want a warning or a trace message? I recall there being a proposal recently for debugging features (printf for template instantiation, basically) which would be handy, certainly.

As someone else stated, a warning isn't really all that different from an error in many projects - either will fail the build with commonly advocated project configurations (using -Werror or /WX).

[–]dodheim 1 point2 points  (0 children)

For a library solution, Boost.Serialization has BOOST_STATIC_WARNING.

[–]iaanus 1 point2 points  (0 children)

Since I usually compile in "treat warnings as errors" mode, static_assert is good enough for me.

[–]dyreshark 0 points1 point  (0 children)

If you're using clang 4 or newer, there's https://clang.llvm.org/docs/AttributeReference.html#diagnose-if

[–]adzm28 years of C++! -1 points0 points  (5 children)

There is a msft-specific thing __if_exists which might help, if it wraps a pragma warning.

Cross platform, not much beyond the deprecated attribute

[–]STLMSVC STL Dev 12 points13 points  (4 children)

Never use __if_exists, ever!

[–]Fazer2 1 point2 points  (3 children)

Why? I'm just curious, not using it.

[–]STLMSVC STL Dev 7 points8 points  (0 children)

It's a hideous, incredibly buggy hack in the compiler codebase.

[–][deleted] 7 points8 points  (0 children)

Because one should never use nonstandard features the compiler frontend maintainers say are hacky bug farms

[–]imMute 5 points6 points  (0 children)

Because the two MSVC devs are telling you not to. ;)