This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118c. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-10-11
14.4 [except.handle] paragraph 3 contains the following text:
A handler is a match for a throw-expression with an object of type E if
- The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv- qualifiers), or
- the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
- the handler is of type cv1 T* cv2 and E is a pointer type that can be converted to the type of the handler by either or both of
- a standard pointer conversion (7.3.12 [conv.ptr]) not involving conversions to pointers to private or protected or ambiguous classes
- a qualification conversion
I propose to alter this text to allow to catch exceptions with ambiguous public base classes by some of the public subobjects. I'm really sure that if someone writes:
try {
// ...
}
catch (Matherr& m) {
// ...
}
he really wants to catch all Matherrs rather than to allow
some of the Matherrs to escape:
class SomeMatherr : public Matherr { /* */ };
struct TrickyBase1 : public SomeMatherr { /* */ };
struct TrickyBase2 : public SomeMatherr { /* */ };
struct TrickyMatherr : public TrickyBase1, TrickyBase2 { /* */ };
According to the standard TrickyMatherr will leak through the catch (Matherr& m) clause. For example:
#include <stdio.h>
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : B1, B2 {}; // D() has two B() subobjects
void f() { throw D(); }
int main()
{
try { f(); }
catch (B& b) { puts("B&"); } // passed
catch (D& d) { puts("D&"); } // really works _after_ B&!!!
}
Also I see one more possible solution: to forbid objects with ambiguous base classes to be "exceptional objects" (for example Borland C++ goes this way) but it seems to be unnecessary restrictive.
Notes from the 10/01 meeting:
The Core Working Group did not feel this was a significant problem. Catching either of the ambiguous base classes would be surprising, and giving an error on throwing an object that has an ambiguous base class would break existing code.