Search code examples
c++c++11inheritancenoreturn

Overriding a [[noreturn]] virtual function


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.


Solution

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