Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have two or more active exceptions at the same time?

C++17 introduces a new function std::uncaught_exceptions:

Detects how many exceptions have been thrown or rethrown and not yet entered their matching catch clauses.

The following code:

#include <iostream>

using namespace std;

struct A
{
    ~A()
    {
        cout << std::uncaught_exceptions() << endl;
    }
};

int main()
{
    try
    {
        try
        {

            A a1;
            throw 1;
        }
        catch (...)
        {
            A a2;
            throw;
        }
    }
    catch (...)
    {
        A a3;
    }   
}

outputs:

1

1

0

Is it possible to have two or more active exceptions at the same time?

Is there any example?

like image 865
xmllmx Avatar asked Jan 04 '18 03:01

xmllmx


People also ask

Can you throw 2 exceptions?

You can't throw two exceptions.

What would happen if two software exceptions occur at exactly the same time?

However, in all the languages I know there can't ever be multiple exceptions at the same time (in the same thread). If an exception has been thrown, it travels up the call stack until it's caught, with no code executing during this time. If the exception is not caught, the program crashes before another can be thrown.

Can you have multiple exceptions in Python?

By handling multiple exceptions, a program can respond to different exceptions without terminating it. In Python, try-except blocks can be used to catch and respond to one or multiple exceptions.

Can you catch two exceptions Java?

In Java SE 7 and later, we can now catch more than one type of exception in a single catch block. Each exception type that can be handled by the catch block is separated using a vertical bar or pipe | .


1 Answers

Yes. Throw an exception from a destructor that was called due to stack unwinding from handling another exception:

struct D
{
  ~D()
  {
    std::cout << std::uncaught_exceptions() << std::endl;
  }
};

struct E
{
  ~E()
  {
    try
    {
      D d_;
      throw 2;
    }
    catch(...)
    {
      std::cout << std::uncaught_exceptions() << std::endl;
    }
  }
};

int main()
{
  try
  {
    D d;
    E e;
    throw 1;
  }
  catch(...)
  {
  }
}

d's destructor will be called while 1 is still an active exception. So std::uncaught_exceptions() inside ~d will be 1.

For e, its destructor will be called while 1 is an active exception. Its destructor will be called. It will construct a D, then throw again. But since neither 1 nor 2 have been caught at this point, std::uncaught_exceptions() inside of ~d_ will be 2.

The whole purpose of std::uncaught_exceptions is to detect this very condition. It allows you to know if an object is being destroyed due to stack unwinding or through normal execution. This lets you know if you should do different kinds of cleanup. Consider a RAII object that will rollback a transaction if it is destroyed due to stack unwinding.

like image 159
Nicol Bolas Avatar answered Oct 17 '22 09:10

Nicol Bolas