At my workplace, we have a different internal name for noreturn
attribute. Suppose it is INTERNAL_DONT_RETURN
I am writing a member function of a class where I do something like
INTERNAL_DONT_RETURN void foo() const
{
if(!*this)
{
throw CoolException();
}
m_call_throw();
}
This m_call_throw() is a private class member std::function<void()>m_call_throw
which gets populated in the class's constructor as a lambda. This lambda does nothing but
m_call_throw([uncoolID]() { throw UncoolException(uncoolID); })
Now both, gcc-4.9.3 and clang gives me following warning
error: function declared 'noreturn' should not return [-Werror,-Winvalid-noreturn]
}
^
I have already consulted this and this question but none of them explained the cause of above warning.
1) Is compiler implicitly adding return
as explained here ?
2) Even when I am throwing exceptions why does compiler believe that my function will return?
3) noreturn attribute mentions that
The noreturn keyword does not affect the exceptional path when that applies: a noreturn-marked function may still return to the caller by throwing an exception or calling longjmp.
Is this relevant to my problem?
But you do return! You return by falling of the end of the function, if the if-statement is false. You may know this can never happen because m_call_throw()
never returns either (does it?), but the compiler apparently doesn't understand this logic.
Is m_call_throw()
marked as noreturn? If not, add it. And if the compiler doesn't pick up on that, you could add an additional throw at the end of the function which you know is never reached but which should silence the warning.
The compiler cannot prove the function will always throw. This is not a bug — there always will be cases that a compiler cannot prove either way.
Whether it should warn you or not is an interesting question. Warning you means it will sometimes report a bug that is not there; not warning you means it will sometimes miss a real bug.
You can easily make the warning non-fatal, or silence it in a number of ways. Disable it for this particular file, or add a call to abort
at the end. There are tradeoffs to be made in each case, but that's life.
If you can switch from a lambda/std::function to a normal member function, just do so, and make it noreturn
. Alas, you cannot have a noreturn
function type or a noreturn
std::function
or a noreturn
lambda, which is IMHO a bug in the language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With