CppNoob
CppNoob

Reputation: 2400

Rethrowing multiple instances of exception_ptr containing same exception

Is the behavior of the following snippet well-defined?

std::exception_ptr eptr;

try {
  ...
} catch (...) {
  eptr = std::current_exception();
}

std::exception_ptr eptr2(eptr);

std::vector<std::exception_ptr> eptrs{eptr, eptr2};

for (auto& exc: eptrs) try {
  std::rethrow_exception(exc);
} catch(std::exception& e) {
  std::cout << e.what() << '\n';
}

If so, does this require that the exception object itself (not just exception_ptr) be copyable?

Upvotes: 2

Views: 547

Answers (1)

namezero
namezero

Reputation: 2293

I cannot quote the standard, but looking at the documentation for std::exception pointer it states:

It is a shared pointer-like type: The pointed exception is guaranteed to remain valid for as long as at least one exception_ptr points to it, potentially extending its lifetime beyond the scope of a catch statement or across threads.

The exception_ptr itself may be copied:

Being copied, including being copied a null-pointer value (or nullptr).

So yes, the behavior is defined. Since it is a shared pointer-like type, there is no copy requirement for the contained exception object

This article explains it a bit further:

The original proposal for the feature required that the exception was copied when it was captured with std::current_exception, but under pressure from implementors that use the "Itanium ABI" (which is actually used for other platforms too, such as 64-bit x86 linux and MacOSX), the requirement was lessened to allow reference counting the exceptions instead. The problem they cited was that the ABI didn't store the copy constructor for exception objects, so when you called std::current_exception() the information required to copy the object was not present.

Upvotes: 3

Related Questions