The [[noreturn]]
attribute can be applied to functions that are not meant to return. For example:
[[noreturn]] void will_throw() { throw std::runtime_error("bad, bad, bad ...."); }
But I've encountered the following situation (no, I didn't design this):
class B {
public:
virtual void f() { throw std::runtime_error(""); }
};
class D : public B {
void f() override { std::cout << "Hi" << std::endl; }
};
I would really like to place the attribute [[noreturn]]
on the B::f()
declaration. But I'm unclear as to what happens to the override in the derived class. Successfully returning from a [[noreturn]]
function results in undefined behavior, and I certainly don't want that if an override also inherits the attribute.
The question: By overriding [[noreturn] virtual void B::f()
, do I inherit the [[noreturn]]
attribute?
I've looked through the C++14 standard, and I'm having trouble determining if attributes are inherited.
In practice, neither g++, clang nor MSVC consider the [[noreturn]]
attribute as inherited
#include <iostream>
struct B {
public:
[[noreturn]] virtual void f() { std::cout << "B\n"; throw 0; }
};
struct D : public B {
void f() override { std::cout << "D\n"; }
};
int main()
{
try { B{}.f(); } catch(...) {}
D{}.f();
B* d = new D{};
d->f();
}
which prints out "B", "D" and "D" for all three compilers.