C + + Exception (Exception)--the first article--Comprehensive explanation __c++

Source: Internet
Author: User
Tags error handling exception handling function prototype

Summary: catch (Exception &ex) is the class Std:exception;catch (...) captured in all standard library definitions. is to catch all the exceptions.


1. Introduction

Exceptions are a way of running time error handling provided by the language. When it comes to error handling, you probably already have a lot of experience, even if you don't mention the exception, but in order to see the benefits of the exception clearly, we might as well review the common and less common ways of error handling.

Network knowledge of C + + exception

1.1 Common error-handling methods

The return value . We use the return value of functions to flag success or failure, or even the cause of failure. But the biggest problem with this approach is that if the caller does not actively check the return value, it can be accepted by the compiler, you can't do anything to him. This also leads to another problem in C + +: Overloaded functions cannot have only different return values, but have the same parameter table because if the caller does not check the return value, The compiler will not know which overloaded function should be called. Of course, this issue has nothing to do with this article, we put aside. Just remember that the return value may be ignored.

The global status flag . For example, the errno used by system calls. The return value is different, the global state flag allows the function's interface (return value, Parameter table) to be fully exploited. The function should set the value of the global variable to succeed or fail (including the reason) before exiting, and as with the return value, it implicitly requires the caller to check the flag after the call, and the constraint is equally weak. Global variables also cause another problem: multithreading is not secure if multiple threads are assigning values to a global variable at the same time, the caller must be very confused when checking the flag. If you want thread safety, you can refer to the errno solution, which is thread-safe.

1.2 Less commonly used processing methods

setjmp ()/longjmp (). You can think of them as a remote goto statement. In my experience, it seems that they are not often used, and perhaps some of the reasons for the destruction of structured programming style. In C + +, should be more do not use them, because the fatal weakness is longjmp () although will be unwindingstack (the word later), but will not call the object in the stack destructor-fatal bar. For different compilers, it may be possible to add a compilation switch to solve the problem, but it is too generic, which can cause the program to be difficult to migrate.

1.3 Exceptions

Now let's see what the anomaly can solve. For the return value and errno encountered embarrassment, basically does not exist for the exception, if you do not capture (catch) the exception thrown in the program, the default behavior is to cause abort () is invoked, the program is terminated (Coredump). So if your function throws an exception, the caller of the function or caller of the caller, that is, on the current callstack, there must be a place to catch the exception. For setjmp ()/longjmp (), the problem of not being destructor on the stack is also non-existent. Then whether it destroys the structure (for Ooparadigms, perhaps, it should be said to be destroying the process.) ). Obviously not, you can rest assured that after the exception to write the correct logic, and all the error handling to a place, this is not better.

To sum up, in C + + probably the exception can completely replace the other error handling, but if the code is flooded with Try/throw/catch is not a good thing, to know the use of unusual skills, please keep the patience to read:

2. Syntax for exceptions

Here we only discuss some of the syntax-related issues.

2.1try

Try always appears with catch, with a try statement, at least one catch () statement. The block after the try is the place where the exception can be thrown.

2.2catch

A catch takes a parameter, a parameter type, and the name of the parameter is specified by the program, and the name can be ignored if the exception object is not intended to be referenced in the subsequent block of the catch. Parameter types can be build-intype, such as Int,long, char, or an object, a pointer to an object, or a reference. If you want to catch any type of exception, you can use "..." as a catch parameter.

Catch does not necessarily capture all the exceptions thrown in the TryBlock, and the remaining ones that are not captured can be handed over to the upper-level function.

2.3throw

Throw is followed by an instance of a type that is related to a catch as a function call, a catch specifying a formal parameter, and a throw argument. The compiler determines which catch the exception should be handled according to the order in which the catch appears and the parameter type specified by the catch.

Throw does not have to appear in the block after the try, it can appear wherever it is needed, as long as there is a catch to catch it. You can continue to throw even in the block following the catch. At this time there are two situations, one is to throw a new type of exception, which is the same as the ordinary throw. The second is to rethrow the current anomaly, in which case the throw can be expressed without parameters. For example:

try{
...
}
catch (int) {
Throwmyexception ("Hello exception"); Throws a new exception
}
catch (float) {
Throw Re-throw the current floating-point number exception
}

2.4 Function declaration

There is also a place related to the throw keyword, which is the function declaration. For example:

void Foo () throw (int); can only throw int type exception
Voidbar () throw (); Do not throw any exceptions
Voidbaz (); Can throw any type of exception or do not throw an exception

If a function has a throw qualifier in its declaration, it must also appear in the body of the function:

void Foo () throw (int)
{
...
}

Here's a problem, very covert, is that even if you write the Foo () function like the one above, you specify that it can only throw an int exception, and it can actually throw other types of exceptions without being discovered by the compiler:

void Foo () throw (int)
{
throw float; Error. Exception type error. Will be pointed out by the compiler
...
Baz (); That's right. Baz () may throw a non-int exception and the compiler cannot discover it.
}

Voidbaz ()
{
throw float;
}

The immediate consequence of this is that if Baz () throws an exception, and the code that calls Foo () is written in strict compliance with the Declaration of Foo (), then the program will abort (). This once annoyed me, that this mechanism is in no way, but there are some solutions, please refer to the "use of skills" in the relevant issues.

3. Abnormal use skills
3.1 How the exception works

In order to be able to use exceptions with certainty, let's take a look at how exception handling works.

3.1.1unwinding Stack

We know that every time a function call takes place, it performs the protection of the field registers, the parameter stacks, the stack of stacks that are created for the called function, and they all make the stack grow. Each time the function returns, the site is restored and the stack is reduced. We call the process of returning the function back to the scene called Unwindingstack.

The throw statement in exception handling produces the same effect as the function return, and it also throws Unwindingstack. If the catch is not in the direct upper function of the throw, then the unwinding process continues until a suitable catch is found. If no proper catch is available, the last std::unexpected () function is invoked, stating that an unexpected exception is found, which invokes Std::terminate (), which calls abort (), and the program terminates ( Coredump).

The longjmp () mentioned in the introduction will also Unwindingstack, but this is a C function, which, like free () does not call the destructor of the object, does not know that the destructor of the object on the stack is invoked during the unwindingstack process. This is the main difference between it and the exception.

3.1.2RTTI

In the process of Unwindingstack, the program will always try to find a "proper" catch to handle this exception. As we mentioned earlier, the relationship between throw and catch is very much like the relationship between function calls and function prototypes, and more than one catch is like a function being overloaded to accept different types. Based on this assumption, it is no big deal to find a suitable function prototype in the process of finding the appropriate catch to handle the exception and the function overload. But the reality is difficult because overloaded calls can be determined at compile time, and exceptions cannot be thrown, consider the following code:

void Foo () throw (int)
{
throw int;
}

void Bar ()
{
try{
Foo ();
}
catch (int) {
...
}
catch (float) {
...
}
}

void Baz ()
{
try{
Foo ();
}

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.