Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception behavior C++14 vs C++98

I have written following program

#include <iostream>
#include <stdexcept>

class Myclass
{
    public:
    ~Myclass() 
    {
        //throw std::runtime_error("second (in destructor)");
        throw 1;
    }
};

void fun()
{
    Myclass obj;
}
int main()
{   
    try
    {
        fun();      
    }
    catch (const std::exception& e)
    {
       std::cout << e.what();
    }
    catch(...)
    {
       std::cout << " ... default Catch" << std::endl; 
    }
    std::cout << "Normal" << std::endl;
    return 0;
}  

When I run above program in C++98 mode (cpp.sh) it prints

 ... default Catch
Normal

When I run it with C++14 mode, it does not print anything. Why is there a change in this behavior?

I do understand that whenever any exception occurred and any destructor (within stack unwinding process) throws any exception, it terminates the application. But here only one time exception is thrown from try block that is from destructor.

like image 661
gaurav bharadwaj Avatar asked Apr 18 '17 12:04

gaurav bharadwaj


People also ask

What are the two types of exceptions in C++?

There are two types of exceptions: a)Synchronous, b)Asynchronous (i.e., exceptions which are beyond the program's control, such as disc failure, keyboard interrupts etc.). C++ provides the following specialized keywords for this purpose: try: Represents a block of code that can throw an exception.

When should you use exceptions C++?

Use exceptions when the code that handles the error is separated from the code that detects the error by one or more intervening function calls. Consider whether to use error codes instead in performance-critical loops, when code that handles the error is tightly coupled to the code that detects it.

What is exception handling C?

Exception handling is a mechanism that separates code that detects and handles exceptional circumstances from the rest of your program. Note that an exceptional circumstance is not necessarily an error. When a function detects an exceptional situation, you represent this with an object.

What is an exception specification in C++?

Exception specifications are a C++ language feature that indicate the programmer's intent about the exception types that can be propagated by a function. You can specify that a function may or may not exit by an exception by using an exception specification.


2 Answers

Since C++11, a destructor without an explicitly spelled out exception specification has the same exception specification as the default-generated one would have. In your case, the default-generated destructor would be noexcept (most default-generated destructors are), so your destructor is considered noexcept as well. Throwing from a noexcept function automatically calls std::terminate.

If you want the exception to be catchable, declare the destructor as throwing:

~Myclass() noexcept(false)
{
    //throw std::runtime_error("second (in destructor)");
    throw 1;
}

But before you do that, reconsider. It's a bad idea to have throwing destructors.

like image 150
Angew is no longer proud of SO Avatar answered Oct 05 '22 01:10

Angew is no longer proud of SO


Throwing exceptions from destructors is always a bad idea since if there's already an exception in flight (e.g. destructor called during stack unwinding) std::terminate will be called.

That said, C++11 added an implicit noexcept(true) to destructors (except cases listed below) and that means, again, std::terminate if throwing from a noexcept(true) destructor.

§12.4/3

[class.dtor] [ Note: A declaration of a destructor that does not have a noexcept-specifier has the same exception specification as if had been implicitly declared (15.4). — end note ]

and §15.4/14

[except.spec] The exception specification for an implicitly-declared destructor, or a destructor without a noexcept-specifier, is potentially-throwing if and only if any of the destructors for any of its potentially constructed subojects is potentially throwing.

I strongly recommend restructuring your code in order not to throw in destructors.

like image 26
Marco A. Avatar answered Oct 04 '22 23:10

Marco A.