|
1 | 1 | --- |
2 | | -title: "try-except Statement (C)" |
3 | | -ms.date: "11/04/2016" |
| 2 | +title: "try-except statement (C)" |
| 3 | +description: "Microsoft C/C++ implements Structured Exception Handling (SEH) using a try-except statement language extension." |
| 4 | +ms.date: 08/24/2020 |
4 | 5 | helpviewer_keywords: ["try-except keyword [C]", "structured exception handling, try-except", "try-catch keyword [C]", "__try keyword [C]", "__except keyword [C]", "__except keyword [C], in try-except", "try-catch keyword [C], try-except keyword [C]"] |
5 | 6 | ms.assetid: f76db9d1-fc78-417f-b71f-18e545fc01c3 |
6 | 7 | --- |
7 | | -# try-except Statement (C) |
| 8 | +# try-except statement (C) |
8 | 9 |
|
9 | | -**Microsoft Specific** |
| 10 | +**Microsoft-specific** |
10 | 11 |
|
11 | | -The **try-except** statement is a Microsoft extension to the C language that enables applications to gain control of a program when events that normally terminate execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling. |
| 12 | +The `try-except` statement is a Microsoft extension to the C language that enables applications to gain control of a program when events that normally terminate execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling. |
12 | 13 |
|
13 | | -Exceptions can be either hardware- or software-based. Even when applications cannot completely recover from hardware or software exceptions, structured exception handling makes it possible to display error information and trap the internal state of the application to help diagnose the problem. This is especially useful for intermittent problems that cannot be reproduced easily. |
| 14 | +Exceptions may be either hardware- or software-based. Even when applications can't completely recover from hardware or software exceptions, structured exception handling makes it possible to log and display error information. It's useful to trap the internal state of the application to help diagnose the problem. In particular, it's helpful for intermittent problems that aren't easy to reproduce. |
14 | 15 |
|
15 | 16 | ## Syntax |
16 | 17 |
|
17 | | -*try-except-statement*: |
18 | | -**__try** *compound-statement* |
| 18 | +> *`try-except-statement`*:\ |
| 19 | +>  **`__try`** *`compound-statement`* **`__except (`** *`expression`* **`)`** *`compound-statement`* |
19 | 20 |
|
20 | | -**__except (** *expression* **)** *compound-statement* |
21 | | - |
22 | | -The compound statement after the `__try` clause is the guarded section. The compound statement after the **`__except`** clause is the exception handler. The handler specifies a set of actions to be taken if an exception is raised during execution of the guarded section. Execution proceeds as follows: |
| 21 | +The compound statement after the **`__try`** clause is the *guarded section*. The compound statement after the **`__except`** clause is the *exception handler*. The handler specifies a set of actions to take if an exception is raised during execution of the guarded section. Execution proceeds as follows: |
23 | 22 |
|
24 | 23 | 1. The guarded section is executed. |
25 | 24 |
|
26 | 25 | 1. If no exception occurs during execution of the guarded section, execution continues at the statement after the **`__except`** clause. |
27 | 26 |
|
28 | | -1. If an exception occurs during execution of the guarded section or in any routine the guarded section calls, the **`__except`** expression is evaluated and the value returned determines how the exception is handled. There are three values: |
29 | | - |
30 | | - `EXCEPTION_CONTINUE_SEARCH` Exception is not recognized. Continue to search up the stack for a handler, first for containing **try-except** statements, then for handlers with the next highest precedence. |
| 27 | +1. If an exception occurs during execution of the guarded section, or in any routine the guarded section calls, the **`__except`** expression gets evaluated. The value returned determines how the exception is handled. There are three possible values: |
31 | 28 |
|
32 | | - `EXCEPTION_CONTINUE_EXECUTION` Exception is recognized but dismissed. Continue execution at the point where the exception occurred. |
| 29 | + - `EXCEPTION_CONTINUE_SEARCH`: The exception isn't recognized. Continue to search up the stack for a handler, first for containing `try-except` statements, then for handlers with the next highest precedence. |
33 | 30 |
|
34 | | - `EXCEPTION_EXECUTE_HANDLER` Exception is recognized. Transfer control to the exception handler by executing the **`__except`** compound statement, then continue execution at the point the exception occurred. |
| 31 | + - `EXCEPTION_CONTINUE_EXECUTION`: The exception is recognized but dismissed. Continue execution at the point where the exception occurred. |
35 | 32 |
|
36 | | -Because the **`__except`** expression is evaluated as a C expression, it is limited to a single value, the conditional-expression operator, or the comma operator. If more extensive processing is required, the expression can call a routine that returns one of the three values listed above. |
| 33 | + - `EXCEPTION_EXECUTE_HANDLER` The exception is recognized. Transfer control to the exception handler by executing the **`__except`** compound statement, then continue execution at the point the exception occurred. |
37 | 34 |
|
38 | | -> [!NOTE] |
39 | | -> Structured exception handling works with C and C++ source files. However, it is not specifically designed for C++. You can ensure that your code is more portable by using C++ exception handling. Also, the C++ exception handling mechanism is much more flexible, in that it can handle exceptions of any type. |
| 35 | +Because the **`__except`** expression is evaluated as a C expression, it's limited to either a single value, the conditional-expression operator, or the comma operator. If more extensive processing is required, the expression can call a routine that returns one of the three values listed above. |
40 | 36 |
|
41 | 37 | > [!NOTE] |
42 | | -> For C++ programs, C++ exception handling should be used instead of structured exception handling. For more information, see [Exception Handling](../cpp/exception-handling-in-visual-cpp.md) in the *C++ Language Reference*. |
| 38 | +> Structured exception handling works with C and C++ source files. However, it isn't specifically designed for C++. For portable C++ programs, C++ exception handling should be used instead of structured exception handling. Also, the C++ exception handling mechanism is much more flexible, in that it can handle exceptions of any type. For more information, see [Exception handling](../cpp/exception-handling-in-visual-cpp.md) in the *C++ Language Reference*. |
43 | 39 |
|
44 | | -Each routine in an application can have its own exception handler. The **`__except`** expression executes in the scope of the `__try` body. This means it has access to any local variables declared there. |
| 40 | +Each routine in an application can have its own exception handler. The **`__except`** expression executes in the scope of the **`__try`** body. It has access to any local variables declared there. |
45 | 41 |
|
46 | | -The **`__leave** keyword is valid within a **try-except** statement block. The effect of **`__leave** is to jump to the end of the **try-except** block. Execution resumes after the end of the exception handler. Although a **`goto`** statement can be used to accomplish the same result, a **`goto`** statement causes stack unwinding. The **`__leave** statement is more efficient because it does not involve stack unwinding. |
| 42 | +The **`__leave`** keyword is valid within a `try-except` statement block. The effect of **`__leave`** is to jump to the end of the `try-except` block. Execution resumes after the end of the exception handler. Although a **`goto`** statement can be used to accomplish the same result, a **`goto`** statement causes stack unwinding. The **`__leave`** statement is more efficient because it doesn't involve stack unwinding. |
47 | 43 |
|
48 | | -Exiting a **try-except** statement using the `longjmp` run-time function is considered abnormal termination. It is illegal to jump into a `__try` statement, but legal to jump out of one. The exception handler is not called if a process is killed in the middle of executing a **try-except** statement. |
| 44 | +Exiting a `try-except` statement using the `longjmp` run-time function is considered abnormal termination. It isn't legal to jump into a **`__try`** statement, but it's legal to jump out of one. The exception handler isn't called if a process is killed in the middle of executing a `try-except` statement. |
49 | 45 |
|
50 | 46 | ## Example |
51 | 47 |
|
52 | | -Following is an example of an exception handler and a termination handler. See [The try-finally Statement](../c-language/try-finally-statement-c.md) for more information about termination handlers. |
| 48 | +Here's an example of an exception handler and a termination handler. For more information about termination handlers, see [`try-finally` statement (C)](../c-language/try-finally-statement-c.md). |
53 | 49 |
|
54 | | -``` |
| 50 | +```C |
55 | 51 | . |
56 | 52 | . |
57 | 53 | . |
58 | 54 | puts("hello"); |
59 | | -__try{ |
| 55 | +__try { |
60 | 56 | puts("in try"); |
61 | | - __try{ |
| 57 | + __try { |
62 | 58 | puts("in try"); |
63 | 59 | RAISE_AN_EXCEPTION(); |
64 | | - }__finally{ |
| 60 | + } __finally { |
65 | 61 | puts("in finally"); |
66 | 62 | } |
67 | | -}__except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ){ |
| 63 | +} __except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ) { |
68 | 64 | puts("in except"); |
69 | 65 | } |
70 | 66 | puts("world"); |
71 | 67 | ``` |
72 | 68 |
|
73 | | -This is the output from the example, with commentary added on the right: |
| 69 | +Here's the output from the example, with commentary added on the right: |
74 | 70 |
|
75 | | -``` |
| 71 | +```Output |
76 | 72 | hello |
77 | | -in try /* fall into try */ |
78 | | -in try /* fall into nested try */ |
| 73 | +in try /* fall into try */ |
| 74 | +in try /* fall into nested try */ |
79 | 75 | in filter /* execute filter; returns 1 so accept */ |
80 | 76 | in finally /* unwind nested finally */ |
81 | 77 | in except /* transfer control to selected handler */ |
82 | 78 | world /* flow out of handler */ |
83 | 79 | ``` |
84 | 80 |
|
85 | | -**END Microsoft Specific** |
| 81 | +**END Microsoft-specific** |
86 | 82 |
|
87 | 83 | ## See also |
88 | 84 |
|
89 | | -[try-except Statement](../cpp/try-except-statement.md) |
| 85 | +[`try-except` statement (C++)](../cpp/try-except-statement.md) |
0 commit comments