Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly resolve incompatible throw specifiers with implicit virtual destructors?

This code does not compile:

#include <QString>

/* relevant part:
struct QString 
{
  ~QString() noexcept(false) {};
};
*/

class Base
{
public:
    virtual ~Base() = default;
};

class Derived : public Base
{
    QString string_;
};

int main()
{
    return 0;
}

The error is:

error: looser throw specifier for 'virtual Derived::~Derived()'
error:   overriding 'virtual Base::~Base() noexcept (true)'

I have no experience with using exceptions, but I think that the problem is that the QString destructor has no exception specifier and therefore the implicitly created Derived::~Derived has also no exception specifier. This is incompatible with the implicit Base::~Base which is noexcept(true).

If I exclude the QString or replace it with a class with noexcept(true) (such as std::string), the code compiles.

At first I thought that I could solve this by declaring both destructors as noexcept(false):

virtual ~Base() noexcept(false) = default;
virtual ~Derived() noexcept(false) = default;

But all I get is:

error: function 'virtual Base::~Base()' defaulted on its first declaration 
       with an exception-specification that differs from 
       the implicit declaration 'Base::~Base()'
error: looser throw specifier for 'virtual Derived::~Derived() noexcept (false)'
error: overriding 'virtual Base::~Base() noexcept (true)'

I do not use exceptions anywhere in my code, so the thing I am looking for is just a "fix".

like image 722
Martin Drozdik Avatar asked Jun 24 '13 10:06

Martin Drozdik


1 Answers

You seem hosed by your QString, that specified itself throwing in dtor.

I see no easy ways out (beyond using a sensible string): you can bend in the wind specifying your base class dtor as noexcept(false) too, or make Derived dtor explicit and expressing noexcept(true). (I'm not sure if anything good happens if ~QString actually thrown, but that leads toward the first escape route).

like image 181
Balog Pal Avatar answered Oct 24 '22 03:10

Balog Pal