I think this is a gcc error (and since no one has answered this answer yet, I presented it as 70375 ).
Both compilers correctly agree that D{} should be caught according to [except.handle] / 3 , which only verifies that B is the base class of D
But handler initialization is defined in [except.handle] / 15 as:
A variable declared by an exception declaration, such as cv T or cv T& , is initialized from an exception object of type E as follows: - if T is a base class of E , the variable is initialized with a copy (8.5) from the corresponding subobject of the base class of the exception object;
This means that initialization works like:
D __temporary_object{}; B __handler = static_cast<B&>(__temporary_object);
which should be disabled, since the B constructor of the copy is marked explicit (and copy-initialization just doesn't cut it).
source share