3

I've read from C++ primer 5th ed. That a virtual member function that won't throw (noexcept) must be overriden as non-throwing function. The exception is if the virtual member function is defined as a 'deleted' member.

So I've tried this:

struct Foo{
    virtual void func() const noexcept = delete;
};

struct Bar : Foo{
    virtual void func() const noexcept(false) override = delete; // or let the compiler make it implicitly a throwing function  
};
  • But when I compile the code I get the error:

    looser exception specification on overriding virtual function ‘virtual void Bar::func() const noexcept (false)’|
    
  • I've searched on cppreference and found the same idea:

If a virtual function is non-throwing, all declarations, including the definition, of every overrider must be non-throwing as well, unless the overrider is defined as deleted. Here is the code from cppreference:

    struct B {
       virtual void f() noexcept;
       virtual void g();
       virtual void h() noexcept = delete;
    };
    struct D: B {
       void f();              // ill-formed: D::f is potentially-throwing, B::f is non-throwing
       void g() noexcept;     // OK
       void h() = delete;     // OK
    };

And when I compile the program from cppreference I get the same error as my example. (apart from f() which shouldn't compile). So consider I comment out void f(); in struct D. the compiler complains the same for void h() = delete;.

So What is wrong with my compiler? Thank you!

N.B: I've tried the code from cppreference on their website and commented out f() in struct D and the code didn't compile too?!! So is this an error on he website too?

Example with clang and gcc: https://www.godbolt.org/z/f7hzbG

Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
Maestro
  • 2,512
  • 9
  • 24
  • 2
    `noexcept(false)` declares that the function **is** allowed to throw. You are doing exactly what the book instructs you not to do. – Drew Dormann Mar 14 '21 at 21:24
  • @DrewDormann: What about the cppreference example then? – Maestro Mar 14 '21 at 21:25
  • 1
    @DrewDormann I think the important thing is the `= deleted` So the rule about not doing it doesn't apply to deleted functions... – Jerry Jeremiah Mar 14 '21 at 21:30
  • Related: https://stackoverflow.com/questions/38279368/is-there-any-point-in-declaring-a-deleted-function-as-noexcept – Jerry Jeremiah Mar 14 '21 at 21:31
  • Visual Studio does accept it in C++17 mode. Maybe the other compilers haven't implemented that detail yet, you could report it to them. – Marc Glisse Mar 14 '21 at 21:42
  • @MarcGlisse: I've run it on VC++ online IDE: `https://rextester.com/l/cpp_online_compiler_visual` but doesn't compile too! I got this error: `Error(s): source_file.cpp(10): error C2694: 'void Bar::func(void) noexcept(false) const': overriding virtual function has less restrictive exception specification than base class virtual member function 'void Foo::func(void) noexcept const' source_file.cpp(10): note: see declaration of 'Bar::func' source_file.cpp(6): note: see declaration of 'Foo::func' Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64` – Maestro Mar 14 '21 at 21:46
  • 2
    Did you enable C++17 mode as I suggested? It does compile on godbolt. – Marc Glisse Mar 14 '21 at 22:04
  • @MarcGlisse: Yes I've tried it using C++17 on VC++ and it works. – Maestro Mar 15 '21 at 20:34

0 Answers0