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.
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.
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