Learn the terminate () function for Exception Handling

Source: Internet
Author: User

 


Exception Handling is a subtle problem. you should handle all exceptions as elegantly as possible. To achieve this goal, you need to learn the terminate () function.

The terminate () function is called when the program throws an exception and the exception is not captured, as shown below:

# Include
# Include

Void on_terminate ()
{
Std: cout <"terminate () function called! "<Std: endl;
Std: cin. get ();
}

Int main ()
{
// If VC6 is used, remove the prefix "std :".
Std: set_terminate (on_terminate );
Throw std: exception ();
Std: cout <"terminate () function is not called! "<Std: endl;
Std: cin. get ();
Return 0;
}

The solution to avoid this situation looks simple at the beginning:

Int main ()
{
Try
{
/* Code */
}
Catch (std: exception & exc)
{
// Logs or other processing
}
Catch (...)
{
// Record "Unknown exception"
}
Return 0;
}

However, in multi-threaded applications, the situation becomes a bit complicated, because each thread you create must have the above (catch) processing process.

However, the terminate () function is called in many other cases, including:

When you throw an exception and in its copy constructor, another exception is thrown.
An exception is thrown when the stack is expanded. At this time, the Destructor throws an exception.
When an exception is thrown by the constructor or destructor of a static object.
When a function registered with atexit throws an exception.
When you write "throw;" in the Code (this means that the current exception is thrown again), but there is no current exception.
When a function throws an exception, the exception is not allowed.
When the default unexpected () processing process is called
The following code demonstrates the results in various cases:

# Include
# Include

Void on_terminate ()
{Std: cout <"terminate () function called! "<Std: endl;
Std: cin. get ();}

/// // [1]
Struct custom_exception
{
Custom_exception (){}
Custom_exception (const custom_exception &)
{Throw std: exception ();}
};

Void case_1 ()
{
Try
{Throw custom_exception ();}
Catch (...)
{}
}

/// // [2]
Struct throw_in_destructor
{
~ Throw_in_destructor () {throw std: exception ();}
};
Void case_2 ()
{
Try
{
Throw_in_destructor temp;
Throw std: exception ();
}
Catch (...)
{}
}

/// // [3]
Struct static_that_throws
{
Static_that_throws () {throw std: exception ();}
};

Void case_3 ()
{
// Note: Using try/catch blocks to enclose the following code does not work.
Static static_that_throws obj;
}

//// // [4]
Void throw_at_exit ()
{Throw std: exception ();}

Void case_4 ()
{Atexit (throw_at_exit );}

/// // [5]
Void case_5 ()
{Throw ;}

//// // [6]
Class custom_6_a {};
Class custom_6_ B {};

Void func_violating_exception_specification_6 () throw (std: exception)
{Throw custom_6_a ();}

// Note: According to our example, we should only throw
// Std: exception (in the function func_violating_exception_specification
// The exception described in the definition); but we didn't do this,
// Therefore, terminate () is called
Void on_unexpected ()
{Throw custom_6_ B ();}

Void case_6 ()
{
Std: set_unexpected (on_unexpected );
Try
{Func_violating_exception_specification_6 ();}
Catch (...)
{}
}

/// // [7]
Class custom_7 {};

Void func_violating_exception_specification_7 () throw (std: exception)
{Throw custom_7 ();}

Void case_7 ()
{
Try
{Func_violating_exception_specification_7 ();}
Catch (...)
{}
}

Int main ()
{
Std: set_terminate (on_terminate );
// Note: make sure that only the annotation of the following call is removed at a time,
// Isolate each situation during analysis
Case_1 ();
// Case_2 ();
// Case_3 ();
// Case_4 ();
// Case_5 ();
// Case_6 ();
// Case_7 ();
Return 0;
}
Although you should try to prevent the terminate () function from being called, we recommend that you create your own terminate () processing process. The only reasonable thing you need to do in your processing is to record a message to the log. In any case, make sure that your log does not throw any exceptions.
Std: ostream & get_log () {/* code */}

Void on_terminate ()
{
Std: ostream & log = get_log ();
// Make sure that we will not throw anything!
Try
{
Log. exceptions (std: ios_base: goodbit );
}
Catch (...)
{}
Log <"terminate () is called! "<Std: endl;
}

Int main ()
{
Std: set_terminate (on_terminate );
//...
}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.