Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get reference to std::exception held by std::exception_ptr

I am trying to get reference to std::exception which is held by std::exception_ptr.

Here's what I have tried:

#include <iostream>

using namespace std::literals;

auto unwrap(std::exception_ptr ptr) -> const std::exception &
{
    try {
        std::rethrow_exception(ptr);
    } catch (std::exception &e) {
        return e;
    }
}

int main()
{
    const auto ptr = std::make_exception_ptr(std::runtime_error{"test"});
    const auto &exp = unwrap(ptr);
    std::cout << exp.what() << std::endl;
    return 0;
}

With GCC, stdout shows "test" which is what I expected. However, with MSVC 2019, stdout shows "Unknown exception".

Is there any undefined, unspecified, or implementation dependent behavior in my source code? Or, is it a compiler/standard library implementation bug?

like image 695
xylosper Avatar asked Nov 15 '22 21:11

xylosper


1 Answers

MSVC makes copies of your exception for some reason. Not sure if this is allowed by the standard or not (someone please clarify). The following code

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

using namespace std::literals;

struct myerror : std::runtime_error
{
    using std::runtime_error::runtime_error;

    myerror(const myerror& o) : myerror(o.what())
    {
        std::cout << "exception is copied\n";
    }

    myerror(const myerror&& o) noexcept : myerror(o.what())
    {
        std::cout << "exception is moved\n";
    }
};

auto unwrap(std::exception_ptr ptr) -> const std::exception&
{
    try {
        std::rethrow_exception(ptr);
    }
    catch (std::exception const& e) {
        std::cout << e.what() << std::endl;
        return e;
    }
}

int main()
{
    std::exception_ptr ptr;
    try
    {
        throw myerror{ "test" };
    }
    catch (...)
    {
        ptr = std::current_exception();
    }
    const auto& exp = unwrap(ptr);
    std::cout << exp.what() << std::endl;
    return 0;
}

prints with MSVC (16.9):

exception is copied
exception is copied
test
Unknown exception

and with clang:

test
test

So your exception reference is dangling in MSVC's case.

godbolt

like image 50
Timo Avatar answered Jan 04 '23 15:01

Timo