While examining what exception_ptr does, the C++11 standard says (18.8.5/7) that:
Use of rethrow_exception on exception_ptr objects that refer to the same exception object shall not introduce a data race. [ Note: if rethrow_exception rethrows the same exception object (rather than a copy), concurrent access to that rethrown exception object may introduce a data race…
I don’t find the case where this weird “Note” applies, since the described effect of rethrow_exception is “Throws: the exception object to which p refers” but 15.1/3, describing the general exception throwing process mandates that “throwing an exception copy-initializes a temporary object, called the exception object.”
The weird note would imply that rethrow_exception skips this copy-initialization. But is this really possible?
Yes, it looks like a deficiency in the standard. For a rethrowing throw-expression i.e.
throw;without an operand, 15.1p8 says:That is:
If the implementation of
current_exceptioncopies the currently handled exception object, there’s no way to tell whetherrethrow_exceptioncopies or not, but if it refers to the exception object then we can check:Every implementation I’ve tried it on prints
1 1;0 0is allowed ifcurrent_exceptioncopies;0 1is obviously impossible, while the standard in its current state appears to require1 0. The fix would be for 18.8.5p10 to be clarified with language similar to 15.1p8, either allowing or mandatingrethrow_exceptionto not copy the exception object pointed to by theexception_ptr.Most Throws: specifications in the standard just name a type (Throws:
bad_alloc) or use the indefinite article (Throws: an exception of type …); the only other exception specifications to use the definite article are those offuture::getandshared_future::get, so any resolution should probably address those as well.