Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the C++ standard say about overriding a throw() function with noexcept?

Tags:

c++

c++11

The following seems to compile on a couple of compilers that I've tried:

class A
{
public:
    virtual void foo() throw() = 0;
};

class B : public A
{
public:
    virtual void foo() noexcept override { }
};

It seems that one can override a throw() function with the newer noexcept specification. I also tried the opposite (overriding noexcept with throw()) and it seems to work. Why is that? Is this undefined behavior or is this allowed?

Please note that code generation is affected by noexcept vs throw(). They also do not have equivalent behavior since noexcept calls a different termination function than throw(). An ideal answer will call out the differences in behavior and why they do or do not matter in this case.

like image 254
Cicada Avatar asked Oct 24 '16 19:10

Cicada


1 Answers

You can even do this without overriding:

void f() throw();
void f() noexcept { throw 1; }

[except.spec]/9 makes it clear that it is the specification on the definition that controls what happens:

Whenever an exception of type E is thrown and the search for a handler ([except.handle]) encounters the outermost block of a function with an exception specification that does not allow E, then,

  • if the function definition has a dynamic-exception-specification, the function std::unexpected() is called ([except.unexpected]),

  • otherwise, the function std::terminate() is called ([except.terminate]).

This isn't a problem because whatever special handling for this happens in the callee, not the caller; all the caller needs to know is that no exception will ever leave the function.

like image 193
T.C. Avatar answered Sep 18 '22 11:09

T.C.