Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?

I have a std::exception_ptr with an exception inside it. I am going to invoke std::rethrow_exception to get the actual exception, will the exception be valid after the catch statement? My guess here is that since I still hold the std::exception_ptr it will still be valid.

See the example:

std::exception_ptr ePtr = initialize_somewhere_else();
std::runtime_error* a=NULL;
try {
    std::rethrow_exception(ePtr);
} catch(std::runtime_error& e) {
    a = &e;
}
std::cout << a << ", " << a->what() << std::endl;

Note: In my tests using Clang this does work.

like image 783
André Puel Avatar asked Oct 19 '22 10:10

André Puel


1 Answers

Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?

Yes. You can think of exception_ptr as a reference-counted pointer to the exception. The exception will live for as long as an exception_ptr refers to it, and no longer.

Additionally, rethrow_exception does not make a copy.

Sorry, I think I've given an incorrect answer.

Here is a detection test:

#include <iostream>
#include <exception>
#include <stdexcept>


int
main()
{
    auto ePtr = std::make_exception_ptr(std::runtime_error("some text"));
    std::runtime_error* a = nullptr;
    try
    {
        std::rethrow_exception(ePtr);
    }
    catch(std::runtime_error& e)
    {
        a = &e;
    }
    *a = std::runtime_error("other text");
    try
    {
        std::rethrow_exception(ePtr);
    }
    catch(const std::runtime_error& e)
    {
        std::cout << e.what() << '\n';
    }
}

On gcc and clang this outputs:

other text

This indicates that a and ePtr refer to the exact same object.

However VS, current version according to http://webcompiler.cloudapp.net outputs:

some text

This indicates that a and ePtr refer to different objects.

The question now is whether VS is conforming in this regard. My opinion is that it doesn't really matter. This is a contentious area of the standard, and if contested, the standard will be changed to match existing practice.

It appears to me that rethrow_exception makes a copy on VS, and that implies that the lifetime of e in the original question is not guaranteed to be tied to ePtr.

like image 116
Howard Hinnant Avatar answered Oct 27 '22 16:10

Howard Hinnant