1. Introduction
Inside a
block, we should have access to the
of what was thrown. Currently there is no portable way to get the
from a
, and so if an object is thrown of intrinsic type or a non-polymorphic class type, and caught in a
block, the type of the exception object is unknown.
2. Motivation
2.1. catch (...)
A C++ program can link with a shared library which has incomplete or inaccurate documentation for the exceptions it throws, or the program may link at runtime using
or
to link with a library which it knows very little about. Code in the main program may handle an exception thrown from within the shared library as follows:
#include <exception> // exception, exception_ptr
#include <new> // bad_alloc
#include <typeinfo> // typeid, type_info
extern void SomeLibraryFunction(void) noexcept(false);
int main(void)
{
try
{
SomeLibraryFunction();
}
catch(std::bad_alloc const&)
{
// Attempt safe shutdown when memory is depleted
}
catch(std::exception const &e)
{
std::type_info const &ti = typeid(e);
// As 'std::exception' has a virtual destructor, it is
// a polymorphic type, and so 'typeid' will give us the
// RTTI of the derived class.
}
catch(...)
{
std::exception_ptr const p = std::current_exception();
// We can get a pointer to the exception object, but
// we have no idea of the type of what was thrown
}
}
This proposal will allow us to access the
of the exception object referred by an
, as follows:
catch(...)
{
std::exception_ptr const p = std::current_exception();
std::type_info const &ti = std::typeid_except(p);
}
3. Impact on the standard
This proposal is a pure library extension. It does not require changes to the standard components. Just one short paragraph is to be appended to Section 17.9.7 [support.exception.propagation]. The text addition is less than 30 words, and the addition has no effect on any other part of the standard.
4. Impact on existing code
No existing code becomes ill-formed. The behaviour of all exisiting code is unaffected by this addition to the standard library.
5. Design considerations
For simplicity, the default argument is '
' so that it can be used as follows:
try { throw 52.8L; } catch(...) { std::type_info const &ti = std::typeid_except(); }
6. Proposed wording
The proposed wording is relative to [N4950].
In section 17.9.7 [support.exception.propagation], append a paragraph:
13 type_info const &typeid_except( exception_ptr p = current_exception() ) noexcept;
Returns: A reference to a ‘type_info’ object for the exception object
referred by ‘p’ (17.9.7.1), or ‘typeid(void)’ (7.6.1.8)
if ‘p’ is a null pointer.