I am compiling a C++ library, and I have an issue with destructors and noexcept
.
It is my understanding that, since C++11, the default value of noexcept(...)
inside destructors has changed. In particular, now destructors default to noexcept
(that is noexcept(true)
).
Now, I have a library for which I get many compiler warnings due to the fact that the destructor of some classes can throw, but it's not marked noexcept(false)
. So I decided to change that, and add the specification. However, these classes inherited from some common parent Base
, so this forced me to add it also to the parent class destructor, otherwise I get the compiler error overriding ‘virtual Base::~Base() noexcept
.
Of course, I can add noexcept(false)
also to the base class (actually, it is enough to add it there, as far as I understand), but there are lots of classes that inherit from Base
, and they would all inherit the noexcept(false)
attribute (as far as I understand). However, the base class destructor itself will never throw, and only few of the derived classes can actually throw. Therefore, it appears a waste to mark the base class destructor noexcept(false)
only for a few classes.
So, I have two questions:
1) Is there any way around this? I cannot remove the throws in the few derived classes that throw, since they are important.
2) I am not sure how much the compiler optimization could be degraded due to the addition of noexcept(false)
to the base class of (virtually) all the classes in the library. When (if ever) should this concern me?
Edit: on a side note, is there a way to change the default value for noexcept
inside a project? Perhaps a compiler option?
Edit: since there have been many feedback, I owe an edit, with a few remarks:
1) I did not write the library, and I certainly do not plan to rewrite the destructors of many classes. Having to add a noexcept(false)
to a some base classes is already enough of a pain. And resorting to a different library is not an option (for different reasons that go beyond programming).
2) When I said "I cannot remove the throws in the few derived classes that throw, since they are important" I meant that I believe the code should terminate in those case, since something really bad happened and undefined behavior may follow anyways. The throw at least comes with a little explanation of what happened.
3) I understand that throwing in a destructor of a derived class is bad, since it may leak due to the fact that the parent class' destructor is not called (is this correct?). What would be a clean way around if one ought to terminate the program (to avoid obscure bugs later) and still let the user know what happened?