C ++ and Windows Exception Handling (try, catch; _ Try ,__ finally; _ Try, _ try t) -- An Exploration caused by a pen Test

Source: Internet
Author: User
Tags define exception finally block


  int*   p   =   0x00000000;       //   pointer   to   NULL 
    puts( "hello "); 
        puts( "in   try "); 
            puts( "in   try "); 
            *p   =   13;         //   causes   an   access   violation   exception; 
            puts( "in   finally "); 
    }__except(puts( "in   filter "),   1){ 
        puts( "in   except "); 
    puts( "world "); 

    in try
    in try
    in filter
    in finally
    in except

I listed the answers to the questions above.

I have never seen the _ Try statements in the form of C ++. Next I will try and catch; _ Try ,__ finally; _ try, _ handle t: The three tags used for exception handling are described one by one.

  • C ++ Exception Handling: Try, catch
     // possible errors
     // If there is something wrong, just--
     throw ... // Initialize an exception object
catch (type name [formal parameter name]) / * exception specifier * /
catch (type name [formal parameter name])

The exception handling in C ++ is very simple, that is, the above three keywords. Note that throw in C ++ does not have finally in Java or other languages after catch.

Q: Why does C ++ not provide a "finally" structure?
A: Because c ++ provides another mechanism that can completely replace finally, and this mechanism almost always works better than finally: "allocating resources is initialization ". (See section 14.4 of the C ++ programming language) The basic idea is to use a local object to encapsulate a resource, in this way, the destructor of a local object can automatically release resources. In this way, programmers will not "forget to release resources. [Note: The "lifecycle" mechanism of the C ++ object is remembered for him: O)] The following is an example:

class File_handle {
        FILE* p;
        File_handle(const char* n, const char* a)
            { p = fopen(n,a); if (p==0) throw Open_error(errno); }

        File_handle(FILE* pp)
            { p = pp; if (p==0) throw Open_error(errno); }

        ~File_handle() { fclose(p); }

        operator FILE*() { return p; }
        // ...

    void f(const char* fn)
        File_handle f(fn,"rw");    // open fn for reading and writing
        // use file through f

In a system, each resource requires a "Resource Bureau handle" object, but we do not have to write a "finally" statement for each resource. In an actual system, resources are acquired and released much more frequently than the types of resources. Therefore, the "resource allocation is initialization" mechanism produces less code than the "finally" mechanism.


Now, let's look at the other two sets of exception model mechanisms. They are the seh model provided on Windows operating systems, that is, when calling in C ++, it is actually calling Windows APIs.

Seh, also known as structured exception handling, is a way to handle exceptions when designing a Windows operating system.

  • _ Try, _ partition t

This set of exception handling mechanisms is very similar to C ++, except that the keyword is catch rather than catch.

Catch and catch t are different:The catch keyword is often followed by a function parameter. It can be an exception data object of various types, but the _ struct t keyword is different, it is followed by an expression (it can be an expression of various types)

The following is an example:

void main ()
     puts ("hello");
     // define monitored code modules
         puts ("in try");

     // define exception handling module
     __except (1)
         puts ("in except");
     puts ("world");

1. The monitored code module is executed (that is, the Code defined by _ Try );
2. If no exception occurs during the above code execution, the control flow will be transferred to the Code module after the _ limit t clause;
3. Otherwise, if an exception occurs, the control flow enters the expression after _ expect T.Calculate the value of this expression.Then, the corresponding processing is determined based on this value.

Exception_continue_execution (-1) The exception is ignored. The control flow continues to run after the exception occurs.
Prediction_continue_search (0) exceptions are not identified, that is, the current _ partition t module is not the correct Exception Handling Module corresponding to this exception error. The system continues to search for an appropriate _ partition t module in the try-release T domain on the previous layer.
Prediction_execute_handler (1) the exception has been identified, that is, the current Exception error. The system has found and confirmed that the _ HANDLE t module is the correct Exception Handling Module. The control flow enters the _ blocks t module.


(1) The C ++ exception model is defined by the try-catch syntax, while the seh exception model is defined by the try-catch syntax;

(2) similar to the C ++ exception model, the try-example t also supports multi-layer try-example t nesting.

(3) Unlike the C ++ exception model, in the try-try t model, a try block can only have one limit t block. In the C ++ exception model, A try block can have multiple catch blocks.

(4) similar to the C ++ exception model, in the try-try t model, the rules for searching the exception module are also carried out step by step. However, the difference is that the C ++ exception model performs a matching search based on the exception object type, while the try-try t model is different, it is determined by the value of an expression. If the expression value is 1 (prediction_execute_handler), the exception handling module is found. If the value is 0 (prediction_continue_search ), it indicates to continue searching for other exception handling modules that may match in the try-again t domain of the previous layer. If the value is-1 (prediction_continue_execution), this exception is ignored. Note that this value is rarely used, it can easily lead to unpredictable results, such as endless loops and even program crashes.

(5) The expression following the _ comment t keyword. It can be a variety of expressions. For example, it can be a function call, a conditional expression, or a comma expression, or an integer constant. The most commonly used function expression is a function expression that uses the getexceptioncode () or getexceptioninformation () function to obtain the current Exception error information, so that programmers can effectively control the classification of exception errors.

(6) In the seh Exception Handling Model, exceptions are classified into two categories: system exceptions and software exceptions. The software exception is thrown through the raiseexception () function. The role of the raiseexception () function is similar to the throw statement in the C ++ exception model.

  • _ Try, _ finally

The syntax of a try-finally statement is similar to that of a try-finally statement. The difference is that __finally does not have an expression after it, because the try-finally statement is not used for exception processing, therefore, it does not need an expression to determine the type of the current Exception error. In addition, like the try-Finally t statement, try-finally can also be nested in multiple layers, and a function can have multiple try-finally statements, whether nested, or parallel. Of course, try-finally multi-layer nesting can also be cross-function.

Key points:"No matter under what circumstances, code in the Finally block area will be executed when it leaves the current scope"

void tmain ()
     puts ("hello");

         puts ("__ try block");
         // Note that the following return statement directly returns the function
         puts ("__ finally block");

     puts ("world");

The program running result is as follows:
_ Try Block
_ Finally block
Press any key to continue



_ When a Finally block is executed, there are three situations.

FirstIt is the code executed in the _ Finally block area in sequence. This situation is simple and easy to understand;

SecondWhen the program control flow caused by a goto or return statement leaves the current _ Try block scope, the system automatically calls the _ Finally block code;

ThirdWhen an exception occurs in the _ Try block, the control flow of the program leaves the current _ Try block scope. In this case, the system automatically calls the _ Finally block.

Whether it is 2nd or 3rd cases, there is no doubt that they will cause a lot of system overhead. When the compiler compiles such program code, it will prepare a lot of additional code for both cases.

Generally, it is referred to as "localunwinding" and "globalunwinding" in 2nd cases )". This will be analyzed in detail when we discuss seh implementation later.

In 3rd cases, that is, global expansion caused by exceptions, this may be unavoidable for programmers, this is because when you use the exception handling mechanism to improve program reliability and robustness, it will inevitably lead to other performance overhead. Haha! In fact, the world is fair, and there are gains and losses.

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.