Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should std::current_exception return non-null from catch block in a class's destructor

My coworkers and I think we have found a bug in Visual C++ 2012 and 2013 but we aren't sure. Should the call to std::current_exception in the following code be expected to return a non-null exception_ptr? It seems to on most other compilers we've tried:

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

class A
{
public:

    ~A()
    {
        try
        {
            throw std::runtime_error("oh no"); 
        }

        catch (std::exception &)
        {
            std::clog << (bool)std::current_exception() << std::endl;
        }
    }
};

void foo ()
{
    A aa;
    throw std::runtime_error("oh no");
}

int main(int argc, char **)
{
    try
    {
        foo();
    }
    catch(...)
    {
    }
    return 0;
}

When run under Visual C++ we get "0" (false, which means the exception_ptr returned is null). Other compilers, such as g++, print "1".

like image 728
SCFrench Avatar asked Mar 17 '23 10:03

SCFrench


1 Answers

cppreference says this about std::current_exception:

If called during exception handling (typically, in a catch clause), captures the current exception object and creates an std::exception_ptr that holds either a copy or a reference to that exception object (it is implementation-defined if a copy is made).

If the implementation of this function requires a call to new and the call fails, the returned pointer will hold a reference to an instance of std::bad_alloc

If the implementation of this function requires to copy the captured exception object and its copy constructor throws an exception, the returned pointer will hold a reference to the exception thrown. If the copy constructor of the thrown exception object also throws, the returned pointer may hold a reference to an instance of std::bad_exception to break the endless loop.

If the function is called when no exception is being handled, an empty std::exception_ptr is returned.

Throwing an exception unwind your stack which should call the destructor of your A class on your aa instance, in which you have a simple try/throw/catch bloc of code which catches the exception.

Of course it's not as authoritative as the standard, but it seems to me that g++/clang are right while visual is not (the other way around happens less often :p)

like image 102
Drax Avatar answered Apr 26 '23 12:04

Drax