Skip to content

Commit 5582406

Browse files
author
Colin Robertson
authored
Merge pull request MicrosoftDocs#111 from dipidoo/patch-1
Update try-except-statement.md
2 parents f35932b + 8565608 commit 5582406

File tree

1 file changed

+135
-152
lines changed

1 file changed

+135
-152
lines changed

docs/cpp/try-except-statement.md

Lines changed: 135 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -17,156 +17,138 @@ ms.author: "mblome"
1717
manager: "ghogen"
1818
---
1919
# try-except Statement
20+
2021
**Microsoft Specific**
21-
22-
The following syntax describes a try-except statement:
23-
22+
The **try-except** statement is a Microsoft extension to the C and C++ languages that supports structured exception handling.
23+
2424
## Syntax
2525

26-
```
27-
28-
__try 
29-
{
30-
// guarded code
31-
}
32-
__except ( expression )
33-
{
34-
// exception handler code
35-
}
36-
```
37-
38-
## Remarks
39-
The **try-except** statement is a Microsoft extension to the C and C++ languages that enables target applications to gain control when events that normally terminate program execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling.
40-
41-
For related information, see the [try-finally statement](../cpp/try-finally-statement.md).
42-
43-
Exceptions can be either hardware-based 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.
44-
26+
> **__try** 
27+
> {
28+
> // guarded code
29+
> }
30+
> **__except** ( *expression* )
31+
> {
32+
> // exception handler code
33+
> }
34+
35+
## Remarks
36+
37+
The **try-except** statement is a Microsoft extension to the C and C++ languages that enables target applications to gain control when events that normally terminate program execution occur. Such events are called *exceptions*, and the mechanism that deals with exceptions is called *structured exception handling* (SEH).
38+
39+
For related information, see the [try-finally statement](../cpp/try-finally-statement.md).
40+
41+
Exceptions can be either hardware-based 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.
42+
4543
> [!NOTE]
46-
> Structured exception handling works with Win32 for both 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, C++ exception handling is more flexible, in that it can handle exceptions of any type. For C++ programs, it is recommended that you use the C++ exception-handling mechanism ([try, catch, and throw](../cpp/try-throw-and-catch-statements-cpp.md) statements).
47-
48-
The compound statement after the `__try` clause is the body or 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 body of the guarded section. Execution proceeds as follows:
49-
50-
1. The guarded section is executed.
51-
52-
2. If no exception occurs during execution of the guarded section, execution continues at the statement after the `__except` clause.
53-
54-
3. If an exception occurs during execution of the guarded section or in any routine the guarded section calls, the `__except` *expression* (called the *filter* expression) is evaluated and the value determines how the exception is handled. There are three values:
55-
56-
**EXCEPTION_CONTINUE_EXECUTION (-1)** Exception is dismissed. Continue execution at the point where the exception occurred.
57-
58-
**EXCEPTION_CONTINUE_SEARCH (0)** 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.
59-
60-
**EXCEPTION_EXECUTE_HANDLER (1)** Exception is recognized. Transfer control to the exception handler by executing the `__except` compound statement, then continue execution after the `__except` block.
61-
62-
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.
63-
64-
Each application can have its own exception handler.
65-
66-
It is not valid to jump into a `__try` statement, but valid to jump out of one. The exception handler is not called if a process is terminated in the middle of executing a **try-except** statement.
67-
68-
For more information, see Knowledge Base article Q315937 : HOW TO: Trap Stack Overflow in a Visual C++ Application.
69-
70-
## The __leave Keyword
71-
The `__leave` keyword is valid only within the guarded section of a `try-except` statement, and its effect is to jump to the end of the guarded section. Execution continues at the first statement after the exception handler.
72-
73-
A `goto` statement can also jump out of the guarded section, and it does not degrade performance as it does in a `try-finally` statement because stack unwinding does not occur. However, we recommend that you use the `__leave` keyword rather than a `goto` statement because you are less likely to make a programming mistake if the guarded section is large or complex.
74-
75-
### Structured Exception Handling Intrinsic Functions
76-
Structured exception handling provides two intrinsic functions that are available to use with the **try-except** statement: **GetExceptionCode** and **GetExceptionInformation**.
77-
78-
**GetExceptionCode** returns the code (a 32-bit integer) of the exception.
79-
80-
The intrinsic function **GetExceptionInformation** returns a pointer to a structure containing additional information about the exception. Through this pointer, you can access the machine state that existed at the time of a hardware exception. The structure is as follows:
81-
82-
```
83-
struct _EXCEPTION_POINTERS {
84-
EXCEPTION_RECORD *ExceptionRecord,
85-
CONTEXT *ContextRecord }
44+
> Structured exception handling works with Win32 for both 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, C++ exception handling is more flexible, in that it can handle exceptions of any type. For C++ programs, it is recommended that you use the C++ exception-handling mechanism ([try, catch, and throw](../cpp/try-throw-and-catch-statements-cpp.md) statements).
45+
46+
The compound statement after the `__try` clause is the body or 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 body of the guarded section. Execution proceeds as follows:
47+
48+
1. The guarded section is executed.
49+
50+
2. If no exception occurs during execution of the guarded section, execution continues at the statement after the `__except` clause.
51+
52+
3. If an exception occurs during execution of the guarded section or in any routine the guarded section calls, the `__except` *expression* (called the *filter* expression) is evaluated and the value determines how the exception is handled. There are three values:
53+
54+
**EXCEPTION_CONTINUE_EXECUTION (-1)** Exception is dismissed. Continue execution at the point where the exception occurred.
55+
56+
**EXCEPTION_CONTINUE_SEARCH (0)** 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.
57+
58+
**EXCEPTION_EXECUTE_HANDLER (1)** Exception is recognized. Transfer control to the exception handler by executing the `__except` compound statement, then continue execution after the `__except` block.
59+
60+
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.
61+
62+
Each application can have its own exception handler.
63+
64+
It is not valid to jump into a `__try` statement, but valid to jump out of one. The exception handler is not called if a process is terminated in the middle of executing a **try-except** statement.
65+
66+
For more information, see Knowledge Base article Q315937 : HOW TO: Trap Stack Overflow in a Visual C++ Application.
67+
68+
## The __leave Keyword
69+
70+
The `__leave` keyword is valid only within the guarded section of a **try-except** statement, and its effect is to jump to the end of the guarded section. Execution continues at the first statement after the exception handler.
71+
72+
A `goto` statement can also jump out of the guarded section, and it does not degrade performance as it does in a **try-finally** statement because stack unwinding does not occur. However, we recommend that you use the `__leave` keyword rather than a `goto` statement because you are less likely to make a programming mistake if the guarded section is large or complex.
73+
74+
### Structured Exception Handling Intrinsic Functions
75+
76+
Structured exception handling provides two intrinsic functions that are available to use with the **try-except** statement: `GetExceptionCode` and `GetExceptionInformation`.
77+
78+
`GetExceptionCode` returns the code (a 32-bit integer) of the exception.
79+
80+
The intrinsic function `GetExceptionInformation` returns a pointer to a structure containing additional information about the exception. Through this pointer, you can access the machine state that existed at the time of a hardware exception. The structure is as follows:
81+
82+
```cpp
83+
typedef struct _EXCEPTION_POINTERS {
84+
PEXCEPTION_RECORD ExceptionRecord;
85+
PCONTEXT ContextRecord;
86+
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
8687
```
87-
88-
The pointer types _**EXCEPTION_RECORD** and \_**CONTEXT** are defined in the include file EXCPT.H.
89-
90-
You can use **GetExceptionCode** within the exception handler. However, you can use **GetExceptionInformation** only within the exception filter expression. The information it points to is generally on the stack and is no longer available when control is transferred to the exception handler.
91-
92-
The intrinsic function **AbnormalTermination** is available within a termination handler. It returns 0 if the body of the `try-finally` statement terminates sequentially. In all other cases, it returns 1.
93-
94-
EXCPT.H defines some alternate names for these intrinsics:
95-
96-
**GetExceptionCode** is equivalent to _exception_code
97-
98-
**GetExceptionInformation** is equivalent to _exception_info
99-
100-
**AbnormalTermination** is equivalent to _abnormal_termination
101-
102-
## Example
103-
`// exceptions_try_except_Statement.cpp`
104-
105-
`// Example of try-except and try-finally statements`
106-
107-
`#include <stdio.h>`
108-
109-
`#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION`
110-
111-
`#include <excpt.h>`
112-
113-
`int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {`
114-
115-
`puts("in filter.");`
116-
117-
`if (code == EXCEPTION_ACCESS_VIOLATION) {`
118-
119-
`puts("caught AV as expected.");`
120-
121-
`return EXCEPTION_EXECUTE_HANDLER;`
122-
123-
`}`
124-
125-
`else {`
126-
127-
`puts("didn't catch AV, unexpected.");`
128-
129-
`return EXCEPTION_CONTINUE_SEARCH;`
130-
131-
`};`
132-
133-
`}`
134-
135-
`int main()`
136-
137-
`{`
138-
139-
`int* p = 0x00000000; // pointer to NULL`
140-
141-
`puts("hello");`
142-
143-
`__try{`
144-
145-
`puts("in try");`
146-
147-
`__try{`
148-
149-
`puts("in try");`
150-
151-
`*p = 13; // causes an access violation exception;`
152-
153-
`}__finally{`
154-
155-
`puts("in finally. termination: ");`
156-
157-
`puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");`
158-
159-
`}`
160-
161-
`}__except(filter(GetExceptionCode(), GetExceptionInformation())){`
162-
163-
`puts("in except");`
164-
165-
`}`
166-
167-
`puts("world");`
168-
169-
`}`
88+
89+
The pointer types `PEXCEPTION_RECORD` and `PCONTEXT` are defined in the include file WINNT.H, and `_EXCEPTION_RECORD` and `_CONTEXT` are defined in the include file EXCPT.H
90+
91+
You can use `GetExceptionCode` within the exception handler. However, you can use `GetExceptionInformation` only within the exception filter expression. The information it points to is generally on the stack and is no longer available when control is transferred to the exception handler.
92+
93+
The intrinsic function `AbnormalTermination` is available within a termination handler. It returns 0 if the body of the **try-finally** statement terminates sequentially. In all other cases, it returns 1.
94+
95+
EXCPT.H defines some alternate names for these intrinsics:
96+
97+
`GetExceptionCode` is equivalent to `_exception_code`
98+
99+
`GetExceptionInformation` is equivalent to `_exception_info`
100+
101+
`AbnormalTermination` is equivalent to `_abnormal_termination`
102+
103+
## Example
104+
105+
```cpp
106+
// exceptions_try_except_Statement.cpp
107+
// Example of try-except and try-finally statements
108+
#include <stdio.h>
109+
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
110+
#include <excpt.h>
111+
112+
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
113+
{
114+
puts("in filter.");
115+
if (code == EXCEPTION_ACCESS_VIOLATION)
116+
{
117+
puts("caught AV as expected.");
118+
return EXCEPTION_EXECUTE_HANDLER;
119+
}
120+
else
121+
{
122+
puts("didn't catch AV, unexpected.");
123+
return EXCEPTION_CONTINUE_SEARCH;
124+
};
125+
}
126+
127+
int main()
128+
{
129+
int* p = 0x00000000; // pointer to NULL
130+
puts("hello");
131+
__try
132+
{
133+
puts("in try");
134+
__try
135+
{
136+
puts("in try");
137+
*p = 13; // causes an access violation exception;
138+
}
139+
__finally
140+
{
141+
puts("in finally. termination: ");
142+
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
143+
}
144+
}
145+
__except(filter(GetExceptionCode(), GetExceptionInformation()))
146+
{
147+
puts("in except");
148+
}
149+
puts("world");
150+
}
151+
```
170152

171153
## Output
172154

@@ -181,10 +163,11 @@ in finally. termination:
181163
in except
182164
world
183165
```
184-
185-
**END Microsoft Specific**
186-
187-
## See Also
188-
[Writing an Exception Handler](../cpp/writing-an-exception-handler.md)
189-
[Structured Exception Handling (C/C++)](../cpp/structured-exception-handling-c-cpp.md)
190-
[Keywords](../cpp/keywords-cpp.md)
166+
167+
**END Microsoft Specific**
168+
169+
## See Also
170+
171+
[Writing an Exception Handler](../cpp/writing-an-exception-handler.md)
172+
[Structured Exception Handling (C/C++)](../cpp/structured-exception-handling-c-cpp.md)
173+
[Keywords](../cpp/keywords-cpp.md)

0 commit comments

Comments
 (0)