Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Noexcept promise on derived class constructor: can that be used without promising noexcept on base constructor?

Let's say I have a class

class C : public B {
  public:
    C() noexcept;
}

Does the noexcept specifier require the same promise by the base class? That is, when I am considering using noexcept, do I just look at the behavior of C::C() or do I also need to consider whether B::B() may throw exceptions?

For example, if B::B throws an exception, does that propagate to C::C or to the code that was asking for a new class instance? -- If propagating to C::C, that would be one reason to avoid noexcept for the constructor if a base class is not noexcept for the constructor.

like image 628
rsjaffe Avatar asked Apr 18 '16 21:04

rsjaffe


1 Answers

There is technically no requirement for the base class constructor to be declared noexcept, but it must not throw, when called by a derived constructor that is declared noexcept.

So yes, you do need to consider whether the base class constructor may throw (exceptions or otherwise).

I guess a better way of asking my question is: where does the exception go next?

The calls flow like this:

caller
  -> derived constructor (the noexcept applies to this)
    -> subobject constructors (includes bases)
    - derived constructor body (not a call, but part of the derived constructor that is executed after the subobjects are constructed)

So, if a subobject (whether it be a base or a member) constructor throws, it first goes to the derived constructor, which doesn't and can't†† swallow the exception so it would propagate to the caller, if the constructor wasn't noexcept. But since it is, std::terminate gets called.

If the base doesn't indeed throw as required by the derived, then it does meet the requirement and can itself be declared noexcept so there is rarly reason not to do so. Perhaps, if the base class is part of a library that must support c++03, while the derived class may assume a later standard, it would make sense.

††It can catch with a function-try-block, but those will always throw again.

like image 94
eerorika Avatar answered Sep 24 '22 20:09

eerorika