Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: function declared 'noreturn' should not return

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?

like image 931
Recker Avatar asked Dec 18 '22 14:12

Recker


2 Answers

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.

like image 198
H. Guijt Avatar answered Dec 24 '22 03:12

H. Guijt


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.

like image 32
n. 1.8e9-where's-my-share m. Avatar answered Dec 24 '22 02:12

n. 1.8e9-where's-my-share m.