diff --git a/docs/build/exception-handling-x64.md b/docs/build/exception-handling-x64.md index a5e0cb586a6..3447b9f6aff 100644 --- a/docs/build/exception-handling-x64.md +++ b/docs/build/exception-handling-x64.md @@ -1,5 +1,6 @@ --- title: "x64 exception handling" +description: "Overview of Microsoft C++ exception handling conventions on x64." ms.date: "10/14/2019" helpviewer_keywords: ["C++ exception handling, x64", "exception handling, x64"] ms.assetid: 41fecd2d-3717-4643-b21c-65dcd2f18c93 @@ -297,7 +298,7 @@ typedef struct _DISPATCHER_CONTEXT { } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; ``` -**ControlPc** is the value of RIP within this function. This value is either an exception address or the address at which control left the establishing function. The RIP is used to determine if control is within some guarded construct inside this function, for example, a `__try` block for `__try`/**`__except`** or `__try`/**`__finally`**. +**ControlPc** is the value of RIP within this function. This value is either an exception address or the address at which control left the establishing function. The RIP is used to determine if control is within some guarded construct inside this function, for example, a **`__try`** block for **`__try`**/**`__except`** or **`__try`**/**`__finally`**. **ImageBase** is the image base (load address) of the module containing this function, to be added to the 32-bit offsets used in the function entry and unwind info to record relative addresses. diff --git a/docs/build/reference/eh-exception-handling-model.md b/docs/build/reference/eh-exception-handling-model.md index 4cc1b5619f1..7262d762d7f 100644 --- a/docs/build/reference/eh-exception-handling-model.md +++ b/docs/build/reference/eh-exception-handling-model.md @@ -1,13 +1,13 @@ --- title: "/EH (Exception handling model)" description: "Reference guide to the Microsoft C++ /EH (Exception handling model) compiler options in Visual Studio." -ms.date: "04/14/2020" +ms.date: 08/25/2020 f1_keywords: ["VC.Project.VCCLWCECompilerTool.ExceptionHandling", "/eh", "VC.Project.VCCLCompilerTool.ExceptionHandling"] helpviewer_keywords: ["exception handling, compiler model", "cl.exe compiler, exception handling", "EH compiler option [C++]", "-EH compiler option [C++]", "/EH compiler option [C++]"] no-loc: [SEH, try, catch, throw, extern, finally, noexcept] ms.assetid: 754b916f-d206-4472-b55a-b6f1b0f2cb4d --- -# /EH (Exception handling model) +# `/EH` (Exception handling model) Specifies the exception handling model support generated by the compiler. Arguments specify whether to apply `catch(...)` syntax to both structured and standard C++ exceptions, whether **extern "C"** code is assumed to throw exceptions, and whether to optimize away certain **`noexcept`** checks. @@ -41,7 +41,7 @@ Clears the previous option argument. For example, **`/EHsc-`** is interpreted as ### Default exception handling behavior -The compiler always generates code that supports asynchronous structured exception handling (SEH). By default (that is, if no **`/EHsc`**, **`/EHs`**, or **`/EHa`** option is specified), the compiler supports SEH handlers in the native C++ `catch(...)` clause. However, it also generates code that only partially supports C++ exceptions. The default exception unwinding code doesn't destroy automatic C++ objects outside of [try](../../cpp/try-throw-and-catch-statements-cpp.md) blocks that go out of scope because of an exception. Resource leaks and undefined behavior may result when a C++ exception is thrown. +The compiler always generates code that supports asynchronous structured exception handling (SEH). By default (that is, if no **`/EHsc`**, **`/EHs`**, or **`/EHa`** option is specified), the compiler supports SEH handlers in the native C++ `catch(...)` clause. However, it also generates code that only partially supports C++ exceptions. The default exception unwinding code doesn't destroy automatic C++ objects outside of [`try`](../../cpp/try-throw-and-catch-statements-cpp.md) blocks that go out of scope because of an exception. Resource leaks and undefined behavior may result when a C++ exception is thrown. ### Standard C++ exception handling @@ -53,12 +53,12 @@ When you use **`/EHs`** or **`/EHsc`**, the compiler assumes that exceptions can ### Structured and standard C++ exception handling -The **`/EHa`** compiler option enables safe stack unwinding for both asynchronous exceptions and C++ exceptions. It supports handling of both standard C++ and structured exceptions by using the native C++ `catch(...)` clause. To implement SEH without specifying **`/EHa`**, you may use the **__try**, **`__except`**, and **`__finally`** syntax. For more information, see [Structured exception handling](../../cpp/structured-exception-handling-c-cpp.md). +The **`/EHa`** compiler option enables safe stack unwinding for both asynchronous exceptions and C++ exceptions. It supports handling of both standard C++ and structured exceptions by using the native C++ `catch(...)` clause. To implement SEH without specifying **`/EHa`**, you may use the **`__try`**, **`__except`**, and **`__finally`** syntax. For more information, see [Structured exception handling](../../cpp/structured-exception-handling-c-cpp.md). > [!IMPORTANT] > Specifying **`/EHa`** and trying to handle all exceptions by using `catch(...)` can be dangerous. In most cases, asynchronous exceptions are unrecoverable and should be considered fatal. Catching them and proceeding can cause process corruption and lead to bugs that are hard to find and fix. > -> Even though Windows and Visual C++ support SEH, we strongly recommend that you use ISO-standard C++ exception handling (**`/EHsc`** or **`/EHs`**). It makes your code more portable and flexible. There may still be times you have to use SEH in legacy code or for particular kinds of programs. It's required in code compiled to support the common language runtime ([/clr](clr-common-language-runtime-compilation.md)), for example. For more information, see [Structured exception handling](../../cpp/structured-exception-handling-c-cpp.md). +> Even though Windows and Visual C++ support SEH, we strongly recommend that you use ISO-standard C++ exception handling (**`/EHsc`** or **`/EHs`**). It makes your code more portable and flexible. There may still be times you have to use SEH in legacy code or for particular kinds of programs. It's required in code compiled to support the common language runtime ([`/clr`](clr-common-language-runtime-compilation.md)), for example. For more information, see [Structured exception handling](../../cpp/structured-exception-handling-c-cpp.md). > > We recommend that you never link object files compiled using **`/EHa`** to ones compiled using **`/EHs`** or **`/EHsc`** in the same executable module. If you have to handle an asynchronous exception by using **`/EHa`** anywhere in your module, use **`/EHa`** to compile all the code in the module. You can use structured exception handling syntax in the same module as code that's compiled by using **`/EHs`**. However, you can't mix the SEH syntax with C++ **`try`**, **`throw`**, and **`catch`** in the same function. @@ -111,9 +111,9 @@ For information about exception handling restrictions under **`/clr`**, see [_se ### Runtime exception checks -The **`/EHr`** option forces runtime termination checks in all functions that have a **`noexcept`** attribute. By default, runtime checks may be optimized away if the compiler back-end determines that a function only calls *non-throwing* functions. Non-throwing functions are any functions that have an attribute that specifies no exceptions may be thrown. They include functions marked **`noexcept`**, `throw()`, `__declspec(nothrow)`, and, when **`/EHc`** is specified, **extern "C"** functions. Non-throwing functions also include any that the compiler has determined are non-throwing by inspection. You can explicitly set the default behavior by using **`/EHr-`**. +The **`/EHr`** option forces runtime termination checks in all functions that have a **`noexcept`** attribute. By default, runtime checks may be optimized away if the compiler back-end determines that a function only calls *non-throwing* functions. Non-throwing functions are any functions that have an attribute that specifies no exceptions may be thrown. They include functions marked **`noexcept`**, `throw()`, `__declspec(nothrow)`, and, when **`/EHc`** is specified, **`extern "C"`** functions. Non-throwing functions also include any that the compiler has determined are non-throwing by inspection. You can explicitly set the default behavior by using **`/EHr-`**. -A non-throwing attribute isn't a guarantee that exceptions can't be thrown by a function. Unlike the behavior of a **`noexcept`** function, the MSVC compiler considers an exception thrown by a function declared using `throw()`, `__declspec(nothrow)`, or **extern "C"** as undefined behavior. Functions that use these three declaration attributes don't enforce runtime termination checks for exceptions. You can use the **`/EHr`** option to help you identify this undefined behavior, by forcing the compiler to generate runtime checks for unhandled exceptions that escape a **`noexcept`** function. +A non-throwing attribute isn't a guarantee that exceptions can't be thrown by a function. Unlike the behavior of a **`noexcept`** function, the MSVC compiler considers an exception thrown by a function declared using `throw()`, `__declspec(nothrow)`, or **`extern "C"`** as undefined behavior. Functions that use these three declaration attributes don't enforce runtime termination checks for exceptions. You can use the **`/EHr`** option to help you identify this undefined behavior, by forcing the compiler to generate runtime checks for unhandled exceptions that escape a **`noexcept`** function. ## Set the option in Visual Studio or programmatically @@ -133,8 +133,8 @@ A non-throwing attribute isn't a guarantee that exceptions can't be thrown by a ## See also -[MSVC Compiler Options](compiler-options.md)\ -[MSVC Compiler Command-Line Syntax](compiler-command-line-syntax.md)\ -[Errors and Exception Handling](../../cpp/errors-and-exception-handling-modern-cpp.md)\ -[Exception Specifications (throw)](../../cpp/exception-specifications-throw-cpp.md)\ +[MSVC Compiler options](compiler-options.md)\ +[MSVC Compiler command-line syntax](compiler-command-line-syntax.md)\ +[Errors and exception handling](../../cpp/errors-and-exception-handling-modern-cpp.md)\ +[Exception specifications (throw)](../../cpp/exception-specifications-throw-cpp.md)\ [Structured Exception Handling (C/C++)](../../cpp/structured-exception-handling-c-cpp.md) diff --git a/docs/c-language/summary-of-statements.md b/docs/c-language/summary-of-statements.md index 3742f753e84..be4e226df08 100644 --- a/docs/c-language/summary-of-statements.md +++ b/docs/c-language/summary-of-statements.md @@ -1,61 +1,65 @@ --- -title: "Summary of Statements" -ms.date: "11/04/2016" +title: "Summary of C statements" +description: "A summary of the statement grammar in the Microsoft C implementation." +ms.date: 08/24/2020 ms.assetid: ce45d2fe-ec0e-459f-afb1-80ab6a7f0239 --- -# Summary of Statements - -*statement*:
-    *labeled-statement*
-    *compound-statement*
-    *expression-statement*
-    *selection-statement*
-    *iteration-statement*
-    *jump-statement*
-    *try-except-statement* /\* Microsoft-specific \*/
-    *try-finally-statement* /\* Microsoft-specific \*/ - -*jump-statement*:
-    **`goto`** *identifier* **;**
-    **continue ;**
-    **break ;**
-    **`return`** *expression*opt **;** - -*compound-statement*:
-    **{** *declaration-list*opt *statement-list*opt **}** - -*declaration-list*:
-    *declaration*
-    *declaration-list* *declaration* - -*statement-list*:
-    *statement*
-    *statement-list* *statement* - -*expression-statement*:
-    *expression*opt **;** - -*iteration-statement*:
-    **while (** *expression* **)** *statement*
-    **`do`** *statement* **while (** *expression* **) ;**
-    **for (** *expression*opt **;** *expression*opt **;** *expression*opt **)** *statement* - -*selection-statement*:
-    **if (** *expression* **)** *statement*
-    **if (** *expression* **)** *statement* **`else`** *statement*
-    **switch (** *expression* **)** *statement* - -*labeled-statement*:
-    *identifier* **:** *statement*
-    **`case`** *constant-expression* **:** *statement*
-    **default :** *statement* - -*try-except-statement*: /\* Microsoft-specific \*/
-    **__try** *compound-statement* **__except (** *expression* **)** *compound-statement* - -*try-finally-statement*: /\* Microsoft-specific \*/
-    **__try** *compound-statement* **`__finally`** *compound-statement* +# Summary of C statements + +*`statement`*:
+ *`labeled-statement`*
+ *`compound-statement`*
+ *`expression-statement`*
+ *`selection-statement`*
+ *`iteration-statement`*
+ *`jump-statement`*
+ *`try-except-statement`* /\* Microsoft-specific \*/
+ *`try-finally-statement`* /\* Microsoft-specific \*/ + +*`jump-statement`*:
+ **`goto`** *`identifier`* **`;`**
+ **`continue ;`**
+ **`break ;`**
+ **`return`** *`expression`*opt **`;`**
+ **`__leave ;`** /\* Microsoft-specific1 \*/ + +*`compound-statement`*:
+ **`{`** *`declaration-list`*opt *`statement-list`*opt **`}`** + +*`declaration-list`*:
+ *`declaration`*
+ *`declaration-list`* *`declaration`* + +*`statement-list`*:
+ *`statement`*
+ *`statement-list`* *`statement`* + +*`expression-statement`*:
+ *`expression`*opt **`;`** + +*`iteration-statement`*:
+ **`while (`** *`expression`* **`)`** *`statement`*
+ **`do`** *`statement`* **`while (`** *`expression`* **`) ;`**
+ **`for (`** *`expression`*opt **`;`** *`expression`*opt **`;`** *`expression`*opt **`)`** *`statement`* + +*`selection-statement`*:
+ **`if (`** *`expression`* **`)`** *`statement`*
+ **`if (`** *`expression`* **`)`** *`statement`* **`else`** *`statement`*
+ **`switch (`** *`expression`* **`)`** *`statement`* + +*`labeled-statement`*:
+ *`identifier`* **`:`** *`statement`*
+ **`case`** *`constant-expression`* **`:`** *`statement`*
+ **`default :`** *`statement`* + +*`try-except-statement`*: /\* Microsoft-specific \*/
+ **`__try`** *`compound-statement`* **`__except (`** *`expression`* **`)`** *`compound-statement`* + +*`try-finally-statement`*: /\* Microsoft-specific \*/
+ **`__try`** *`compound-statement`* **`__finally`** *`compound-statement`* + +1 The **`__leave`** keyword is only valid within the **`__try`** block of a *`try-except-statement`* or a *`try-finally-statement`*. ## See also -[Phrase Structure Grammar](../c-language/phrase-structure-grammar.md) +[Phrase structure grammar](../c-language/phrase-structure-grammar.md) diff --git a/docs/c-language/try-except-statement-c.md b/docs/c-language/try-except-statement-c.md index 7805ea50a4a..04a734fa2a5 100644 --- a/docs/c-language/try-except-statement-c.md +++ b/docs/c-language/try-except-statement-c.md @@ -1,89 +1,85 @@ --- -title: "try-except Statement (C)" -ms.date: "11/04/2016" +title: "try-except statement (C)" +description: "Microsoft C/C++ implements Structured Exception Handling (SEH) using a try-except statement language extension." +ms.date: 08/24/2020 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]"] ms.assetid: f76db9d1-fc78-417f-b71f-18e545fc01c3 --- -# try-except Statement (C) +# try-except statement (C) -**Microsoft Specific** +**Microsoft-specific** -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. +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. -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. +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. ## Syntax -*try-except-statement*: -**__try** *compound-statement* +> *`try-except-statement`*:\ +>  **`__try`** *`compound-statement`* **`__except (`** *`expression`* **`)`** *`compound-statement`* -**__except (** *expression* **)** *compound-statement* - -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: +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: 1. The guarded section is executed. 1. If no exception occurs during execution of the guarded section, execution continues at the statement after the **`__except`** clause. -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: - - `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. +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: - `EXCEPTION_CONTINUE_EXECUTION` Exception is recognized but dismissed. Continue execution at the point where the exception occurred. + - `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. - `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. + - `EXCEPTION_CONTINUE_EXECUTION`: The exception is recognized but dismissed. Continue execution at the point where the exception occurred. -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. + - `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. -> [!NOTE] -> 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. +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. > [!NOTE] -> 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*. +> 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*. -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. +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. -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. +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. -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. +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. ## Example -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. +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). -``` +```C . . . puts("hello"); -__try{ +__try { puts("in try"); - __try{ + __try { puts("in try"); RAISE_AN_EXCEPTION(); - }__finally{ + } __finally { puts("in finally"); } -}__except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ){ +} __except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ) { puts("in except"); } puts("world"); ``` -This is the output from the example, with commentary added on the right: +Here's the output from the example, with commentary added on the right: -``` +```Output hello -in try /* fall into try */ -in try /* fall into nested try */ +in try /* fall into try */ +in try /* fall into nested try */ in filter /* execute filter; returns 1 so accept */ in finally /* unwind nested finally */ in except /* transfer control to selected handler */ world /* flow out of handler */ ``` -**END Microsoft Specific** +**END Microsoft-specific** ## See also -[try-except Statement](../cpp/try-except-statement.md) +[`try-except` statement (C++)](../cpp/try-except-statement.md) diff --git a/docs/c-language/try-finally-statement-c.md b/docs/c-language/try-finally-statement-c.md index c483b3e4484..9741974efaf 100644 --- a/docs/c-language/try-finally-statement-c.md +++ b/docs/c-language/try-finally-statement-c.md @@ -1,46 +1,42 @@ --- -title: "try-finally Statement (C)" -ms.date: "11/04/2016" +title: "try-finally statement (C)" +description: "Microsoft C/C++ implements Structured Exception Handling (SEH) using a try-finally statement language extension." +ms.date: 08/24/2020 helpviewer_keywords: ["try-finally keyword [C]", "__finally keyword [C], try-finally statement syntax", "__finally keyword [C]", "structured exception handling, try-finally"] ms.assetid: 514400c1-c322-4bf3-9e48-3047240b8a82 --- -# try-finally Statement (C) +# try-finally statement (C) -**Microsoft Specific** +**Microsoft-specific** The `try-finally` statement is a Microsoft extension to the C language that enables applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The `try-finally` statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine. -*try-finally-statement*: -**__try** *compound-statement* +> *`try-finally-statement`*:\ +>  **`__try`** *`compound-statement`* **`__finally`** *`compound-statement`* -**`__finally`** *compound-statement* +The compound statement after the **`__try`** clause is the guarded section. The compound statement after the **`__finally`** clause is the termination handler. The handler specifies a set of actions that execute when the guarded section is exited. It doesn't matter whether the guarded section is exited by an exception (abnormal termination) or by standard fall through (normal termination). -The compound statement after the `__try` clause is the guarded section. The compound statement after the **`__finally`** clause is the termination handler. The handler specifies a set of actions that execute when the guarded section is exited, whether the guarded section is exited by an exception (abnormal termination) or by standard fall through (normal termination). - -Control reaches a `__try` statement by simple sequential execution (fall through). When control enters the `__try` statement, its associated handler becomes active. Execution proceeds as follows: +Control reaches a **`__try`** statement by simple sequential execution (fall through). When control enters the **`__try`** statement, its associated handler becomes active. Execution proceeds as follows: 1. The guarded section is executed. 1. The termination handler is invoked. -1. When the termination handler completes, execution continues after the **`__finally`** statement. Regardless of how the guarded section ends (for example, via a **`goto`** statement out of the guarded body or via a **`return`** statement), the termination handler is executed before the flow of control moves out of the guarded section. - -The **`__leave** keyword is valid within a `try-finally` statement block. The effect of **`__leave** is to jump to the end of the `try-finally` block. The termination handler is immediately executed. 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. +1. When the termination handler completes, execution continues after the **`__finally`** statement. No matter how the guarded section ends (for example, via a **`goto`** statement out of the guarded body or via a **`return`** statement), the termination handler is executed before the flow of control moves out of the guarded section. -Exiting a `try-finally` statement using a **`return`** statement or 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. All **`__finally`** statements that are active between the point of departure and the destination must be run. This is called a "local unwind." +The **`__leave`** keyword is valid within a `try-finally` statement block. The effect of **`__leave`** is to jump to the end of the `try-finally` block. The termination handler is immediately executed. 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. -The termination handler is not called if a process is killed while executing a `try-finally` statement. +Exiting a `try-finally` statement using a **`return`** statement or the `longjmp` run-time function is considered abnormal termination. It's not legal to jump into a **`__try`** statement, but legal to jump out of one. All **`__finally`** statements that are active between the point of departure and the destination must be run. It's called a *local unwind*. -> [!NOTE] -> 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. +The termination handler isn't called if a process is killed while executing a `try-finally` statement. > [!NOTE] -> 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*. +> 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*. -See the example for the [try-except statement](../c-language/try-except-statement-c.md) to see how the `try-finally` statement works. +See the example for the [`try-except` statement](../c-language/try-except-statement-c.md) to see how the `try-finally` statement works. -**END Microsoft Specific** +**END Microsoft-specific** ## See also -[try-finally Statement](../cpp/try-finally-statement.md) +[`try-finally` statement (C++)](../cpp/try-finally-statement.md) diff --git a/docs/cloud/cloud-and-web-programming-in-visual-cpp.md b/docs/cloud/cloud-and-web-programming-in-visual-cpp.md index 6e5bb4e3fd4..f1b49b6b367 100644 --- a/docs/cloud/cloud-and-web-programming-in-visual-cpp.md +++ b/docs/cloud/cloud-and-web-programming-in-visual-cpp.md @@ -24,7 +24,7 @@ In C++, you have several options for connecting to the web and the cloud. - [OneDrive and SharePoint in Microsoft Graph](https://dev.onedrive.com/README.htm) - The OneDrive API provides a set of HTTP services to connect your application to files and folders in Office 365 and SharePoint Server 2016. + The OneDrive API provides a set of HTTP services to connect your application to files and folders in Microsoft 365 and SharePoint Server 2016. ## Windows and cross-platform networking APIs diff --git a/docs/code-quality/c6242.md b/docs/code-quality/c6242.md index 4069ea73ccd..b5ed044b06d 100644 --- a/docs/code-quality/c6242.md +++ b/docs/code-quality/c6242.md @@ -1,6 +1,7 @@ --- title: C6242 -ms.date: 11/04/2016 +description: "Describes Microsoft C/C++ compiler warning C6242." +ms.date: 08/24/2020 ms.topic: reference f1_keywords: ["C6242"] helpviewer_keywords: ["C6242"] @@ -10,11 +11,11 @@ ms.assetid: 523d46ce-8370-434c-a752-2e3a18cca9a5 > warning C6242: A jump out of this try-block forces local unwind. Incurs severe performance penalty -This warning indicates that a jump statement causes control-flow to leave the protected block of a try-finally other than by fall-through. +This warning indicates that a jump statement causes control-flow to leave the protected block of a `try-finally` other than by fall-through. -Leaving the protected block of a try-finally other than by falling through from the last statement requires local unwind to occur. Local unwind typically requires approximately 1000 machine instructions; therefore, it is detrimental to performance. +Leaving the protected block of a `try-finally` other than by falling through from the last statement requires local unwind to occur. Local unwind typically requires approximately 1000 machine instructions, so it's detrimental to performance. -Use **`__leave** to exit the protected block of a try-finally. +Use **`__leave`** to exit the protected block of a try-finally. ## Example @@ -44,7 +45,7 @@ int f( ) } ``` -To correct this warning, use **`__leave** as shown in the following code: +To correct this warning, use **`__leave`** as shown in the following code: ```cpp #include @@ -74,8 +75,9 @@ int f() } ``` -The use of malloc and free have many pitfalls in terms of memory leaks and exceptions. To avoid these kinds of leaks and exception problems altogether, use the mechanisms that are provided by the C++ Standard Template Library (STL). These include [shared_ptr](/cpp/standard-library/shared-ptr-class), [unique_ptr](/cpp/standard-library/unique-ptr-class), and [vector](/cpp/standard-library/vector). For more information, see [Smart Pointers](/cpp/cpp/smart-pointers-modern-cpp) and [C++ Standard Library](/cpp/standard-library/cpp-standard-library-reference). +The use of `malloc` and `free` have many pitfalls in terms of memory leaks and exceptions. To avoid these kinds of leaks and exception problems altogether, use the mechanisms that are provided by the C++ Standard Library. These include [`shared_ptr`](/cpp/standard-library/shared-ptr-class), [`unique_ptr`](/cpp/standard-library/unique-ptr-class), and [`vector`](/cpp/standard-library/vector). For more information, see [Smart pointers](/cpp/cpp/smart-pointers-modern-cpp) and [C++ Standard Library](/cpp/standard-library/cpp-standard-library-reference). ## See also -[try-finally Statement](/cpp/cpp/try-finally-statement) +[`try-except` statement](/cpp/cpp/try-except-statement)\ +[`try-finally` statement](/cpp/cpp/try-finally-statement) diff --git a/docs/cpp/cleaning-up-resources.md b/docs/cpp/cleaning-up-resources.md index b95844f6441..b93f211232b 100644 --- a/docs/cpp/cleaning-up-resources.md +++ b/docs/cpp/cleaning-up-resources.md @@ -1,24 +1,25 @@ --- -title: "Cleaning up Resources" -ms.date: "11/04/2016" +title: "Cleaning up resources" +description: "How to release resources during a termination handler for structured exception handling." +ms.date: 08/24/2020 helpviewer_keywords: ["termination handlers [C++], cleaning up resources", "exception handling [C++], cleaning up resources", "C++ exception handling, termination handlers", "resources [C++], cleaning up", "exception handling [C++], cleanup code", "try-catch keyword [C++], termination handlers"] ms.assetid: 65753efe-6a27-4750-b90c-50635775c1b6 --- -# Cleaning up Resources +# Cleaning up resources -During termination-handler execution, you may not know which resources are actually allocated before the termination handler was called. It is possible that the **__try** statement block was interrupted before all resources were allocated, so that not all resources were opened. +During termination-handler execution, you may not know which resources have been acquired before the termination handler was called. It's possible that the **`__try`** statement block was interrupted before all resources were acquired, so that not all resources were opened. -Therefore, to be safe, you should check to see which resources are actually open before proceeding with termination-handling cleanup. A recommended procedure is to: +To be safe, you should check to see which resources are open before proceeding with termination-handling cleanup. A recommended procedure is to: 1. Initialize handles to NULL. -1. In the **__try** statement block, allocate resources. Handles are set to positive values as the resource is allocated. +1. In the **`__try`** statement block, acquire resources. Handles are set to positive values as the resource is acquired. 1. In the **`__finally`** statement block, release each resource whose corresponding handle or flag variable is nonzero or not NULL. ## Example -For example, the following code uses a termination handler to close three files and a memory block that were allocated in the **__try** statement block. Before cleaning up a resource, the code first checks to see if the resource was allocated. +For example, the following code uses a termination handler to close three files and release a memory block. These resources were acquired in the **`__try`** statement block. Before cleaning up a resource, the code first checks to see if the resource was acquired. ```cpp // exceptions_Cleaning_up_Resources.cpp diff --git a/docs/cpp/errors-and-exception-handling-modern-cpp.md b/docs/cpp/errors-and-exception-handling-modern-cpp.md index ec366eb2ac9..d9feec12664 100644 --- a/docs/cpp/errors-and-exception-handling-modern-cpp.md +++ b/docs/cpp/errors-and-exception-handling-modern-cpp.md @@ -1,29 +1,31 @@ --- title: "Modern C++ best practices for exceptions and error handling" -ms.date: "11/19/2019" +description: "How Modern C++ supports exceptional programming styles over error codes." +ms.date: 08/24/2020 ms.topic: "conceptual" ms.assetid: a6c111d0-24f9-4bbb-997d-3db4569761b7 --- # Modern C++ best practices for exceptions and error handling -In modern C++, in most scenarios, the preferred way to report and handle both logic errors and runtime errors is to use exceptions. This is especially true when the stack might contain several function calls between the function that detects the error and the function that has the context to know how to handle it. Exceptions provide a formal, well-defined way for code that detects errors to pass the information up the call stack. +In modern C++, in most scenarios, the preferred way to report and handle both logic errors and runtime errors is to use exceptions. It's especially true when the stack might contain several function calls between the function that detects the error, and the function that has the context to handle the error. Exceptions provide a formal, well-defined way for code that detects errors to pass the information up the call stack. -Program errors are generally divided into two categories: logic errors that are caused by programming mistakes, for example, an "index out of range" error, and runtime errors that are beyond the control of programmer, for example, a "network service unavailable" error. In C-style programming and in COM, error reporting is managed either by returning a value that represents an error code or a status code for a particular function, or by setting a global variable that the caller may optionally retrieve after every function call to see whether errors were reported. For example, COM programming uses the HRESULT return value to communicate errors to the caller, and the Win32 API has the GetLastError function to retrieve the last error that was reported by the call stack. In both of these cases, it's up to the caller to recognize the code and respond to it appropriately. If the caller doesn't explicitly handle the error code, the program might crash without warning, or continue to execute with bad data and produce incorrect results. +## Use exceptions for exceptional code + +Program errors are often divided into two categories: Logic errors that are caused by programming mistakes, for example, an "index out of range" error. And, runtime errors that are beyond the control of programmer, for example, a "network service unavailable" error. In C-style programming and in COM, error reporting is managed either by returning a value that represents an error code or a status code for a particular function, or by setting a global variable that the caller may optionally retrieve after every function call to see whether errors were reported. For example, COM programming uses the HRESULT return value to communicate errors to the caller. And the Win32 API has the `GetLastError` function to retrieve the last error that was reported by the call stack. In both of these cases, it's up to the caller to recognize the code and respond to it appropriately. If the caller doesn't explicitly handle the error code, the program might crash without warning. Or, it might continue to execute using bad data and produce incorrect results. Exceptions are preferred in modern C++ for the following reasons: - An exception forces calling code to recognize an error condition and handle it. Unhandled exceptions stop program execution. -- An exception jumps to the point in the call stack that can handle the error. Intermediate functions can let the exception propagate. They do not have to coordinate with other layers. +- An exception jumps to the point in the call stack that can handle the error. Intermediate functions can let the exception propagate. They don't have to coordinate with other layers. -- The exception stack-unwinding mechanism destroys all objects in scope according to well-defined rules after an exception is thrown. +- The exception stack-unwinding mechanism destroys all objects in scope after an exception is thrown, according to well-defined rules. - An exception enables a clean separation between the code that detects the error and the code that handles the error. The following simplified example shows the necessary syntax for throwing and catching exceptions in C++. ```cpp - #include #include #include @@ -54,46 +56,46 @@ int main() } ``` -Exceptions in C++ resemble those in languages such as C# and Java. In the **`try`** block, if an exception is *thrown* it will be *caught* by the first associated **`catch`** block whose type matches that of the exception. In other words, execution jumps from the **`throw`** statement to the **`catch`** statement. If no usable catch block is found, `std::terminate` is invoked and the program exits. In C++, any type may be thrown; however, we recommend that you throw a type that derives directly or indirectly from `std::exception`. In the previous example, the exception type, [invalid_argument](../standard-library/invalid-argument-class.md), is defined in the standard library in the [\](../standard-library/stdexcept.md) header file. C++ does not provide, and does not require, a **finally** block to make sure that all resources are released if an exception is thrown. The resource acquisition is initialization (RAII) idiom, which uses smart pointers, provides the required functionality for resource cleanup. For more information, see [How to: Design for Exception Safety](how-to-design-for-exception-safety.md). For information about the C++ stack-unwinding mechanism, see [Exceptions and Stack Unwinding](exceptions-and-stack-unwinding-in-cpp.md). +Exceptions in C++ resemble ones in languages such as C# and Java. In the **`try`** block, if an exception is *thrown* it will be *caught* by the first associated **`catch`** block whose type matches that of the exception. In other words, execution jumps from the **`throw`** statement to the **`catch`** statement. If no usable catch block is found, `std::terminate` is invoked and the program exits. In C++, any type may be thrown; however, we recommend that you throw a type that derives directly or indirectly from `std::exception`. In the previous example, the exception type, [`invalid_argument`](../standard-library/invalid-argument-class.md), is defined in the standard library in the [``](../standard-library/stdexcept.md) header file. C++ doesn't provide or require a **`finally`** block to make sure all resources are released if an exception is thrown. The resource acquisition is initialization (RAII) idiom, which uses smart pointers, provides the required functionality for resource cleanup. For more information, see [How to: Design for exception safety](how-to-design-for-exception-safety.md). For information about the C++ stack-unwinding mechanism, see [Exceptions and stack unwinding](exceptions-and-stack-unwinding-in-cpp.md). ## Basic guidelines Robust error handling is challenging in any programming language. Although exceptions provide several features that support good error handling, they can't do all the work for you. To realize the benefits of the exception mechanism, keep exceptions in mind as you design your code. -- Use asserts to check for errors that should never occur. Use exceptions to check for errors that might occur, for example, errors in input validation on parameters of public functions. For more information, see the section titled **Exceptions vs. Assertions**. +- Use asserts to check for errors that should never occur. Use exceptions to check for errors that might occur, for example, errors in input validation on parameters of public functions. For more information, see the [Exceptions versus assertions](#exceptions_versus_assertions) section. -- Use exceptions when the code that handles the error might be separated from the code that detects the error by one or more intervening function calls. Consider whether to use error codes instead in performance-critical loops when code that handles the error is tightly-coupled to the code that detects it. +- Use exceptions when the code that handles the error is separated from the code that detects the error by one or more intervening function calls. Consider whether to use error codes instead in performance-critical loops, when code that handles the error is tightly coupled to the code that detects it. -- For every function that might throw or propagate an exception, provide one of the three exception guarantees: the strong guarantee, the basic guarantee, or the nothrow (noexcept) guarantee. For more information, see [How to: Design for Exception Safety](how-to-design-for-exception-safety.md). +- For every function that might throw or propagate an exception, provide one of the three exception guarantees: the strong guarantee, the basic guarantee, or the nothrow (noexcept) guarantee. For more information, see [How to: Design for exception safety](how-to-design-for-exception-safety.md). - Throw exceptions by value, catch them by reference. Don’t catch what you can't handle. -- Don't use exception specifications, which are deprecated in C++11. For more information, see the section titled **Exception specifications and noexcept**. +- Don't use exception specifications, which are deprecated in C++11. For more information, see the [Exception specifications and `noexcept`](#exception_specifications_and_noexcept) section. -- Use standard library exception types when they apply. Derive custom exception types from the [exception Class](../standard-library/exception-class.md) hierarchy. +- Use standard library exception types when they apply. Derive custom exception types from the [`exception` Class](../standard-library/exception-class.md) hierarchy. - Don't allow exceptions to escape from destructors or memory-deallocation functions. ## Exceptions and performance -The exception mechanism has a very minimal performance cost if no exception is thrown. If an exception is thrown, the cost of the stack traversal and unwinding is roughly comparable to the cost of a function call. Additional data structures are required to track the call stack after a **`try`** block is entered, and additional instructions are required to unwind the stack if an exception is thrown. However, in most scenarios, the cost in performance and memory footprint is not significant. The adverse effect of exceptions on performance is likely to be significant only on very memory-constrained systems, or in performance-critical loops where an error is likely to occur regularly and the code to handle it is tightly coupled to the code that reports it. In any case, it's impossible to know the actual cost of exceptions without profiling and measuring. Even in those rare cases when the cost is significant, you can weigh it against the increased correctness, easier maintainability, and other advantages that are provided by a well-designed exception policy. +The exception mechanism has a minimal performance cost if no exception is thrown. If an exception is thrown, the cost of the stack traversal and unwinding is roughly comparable to the cost of a function call. Additional data structures are required to track the call stack after a **`try`** block is entered, and additional instructions are required to unwind the stack if an exception is thrown. However, in most scenarios, the cost in performance and memory footprint isn't significant. The adverse effect of exceptions on performance is likely to be significant only on memory-constrained systems. Or, in performance-critical loops, where an error is likely to occur regularly and there's tight coupling between the code to handle it and the code that reports it. In any case, it's impossible to know the actual cost of exceptions without profiling and measuring. Even in those rare cases when the cost is significant, you can weigh it against the increased correctness, easier maintainability, and other advantages that are provided by a well-designed exception policy. -## Exceptions vs. assertions +## Exceptions versus assertions -Exceptions and asserts are two distinct mechanisms for detecting run-time errors in a program. Use asserts to test for conditions during development that should never be true if all your code is correct. There is no point in handling such an error by using an exception because the error indicates that something in the code has to be fixed, and doesn't represent a condition that the program has to recover from at run time. An assert stops execution at the statement so that you can inspect the program state in the debugger; an exception continues execution from the first appropriate catch handler. Use exceptions to check error conditions that might occur at run time even if your code is correct, for example, "file not found" or "out of memory." You might want to recover from these conditions, even if the recovery just outputs a message to a log and ends the program. Always check arguments to public functions by using exceptions. Even if your function is error-free, you might not have complete control over arguments that a user might pass to it. +Exceptions and asserts are two distinct mechanisms for detecting run-time errors in a program. Use `assert` statements to test for conditions during development that should never be true if all your code is correct. There's no point in handling such an error by using an exception, because the error indicates that something in the code has to be fixed. It doesn't represent a condition that the program has to recover from at run time. An `assert` stops execution at the statement so that you can inspect the program state in the debugger. An exception continues execution from the first appropriate catch handler. Use exceptions to check error conditions that might occur at run time even if your code is correct, for example, "file not found" or "out of memory." Exceptions can handle these conditions, even if the recovery just outputs a message to a log and ends the program. Always check arguments to public functions by using exceptions. Even if your function is error-free, you might not have complete control over arguments that a user might pass to it. ## C++ exceptions versus Windows SEH exceptions -Both C and C++ programs can use the structured exception handling (SEH) mechanism in the Windows operating system. The concepts in SEH resemble those in C++ exceptions, except that SEH uses the **__try**, **`__except`**, and **`__finally`** constructs instead of **`try`** and **`catch`**. In the Microsoft C++ compiler (MSVC), C++ exceptions are implemented for SEH. However, when you write C++ code, use the C++ exception syntax. +Both C and C++ programs can use the structured exception handling (SEH) mechanism in the Windows operating system. The concepts in SEH resemble the ones in C++ exceptions, except that SEH uses the **`__try`**, **`__except`**, and **`__finally`** constructs instead of **`try`** and **`catch`**. In the Microsoft C++ compiler (MSVC), C++ exceptions are implemented for SEH. However, when you write C++ code, use the C++ exception syntax. For more information about SEH, see [Structured Exception Handling (C/C++)](structured-exception-handling-c-cpp.md). -## Exception specifications and noexcept +## Exception specifications and `noexcept` -Exception specifications were introduced in C++ as a way to specify the exceptions that a function might throw. However, exception specifications proved problematic in practice, and are deprecated in the C++11 draft standard. We recommend that you do not use exception specifications except for `throw()`, which indicates that the function allows no exceptions to escape. If you must use exception specifications of the type `throw(`*type*`)`, be aware that MSVC departs from the standard in certain ways. For more information, see [Exception Specifications (throw)](exception-specifications-throw-cpp.md). The **`noexcept`** specifier is introduced in C++11 as the preferred alternative to `throw()`. +Exception specifications were introduced in C++ as a way to specify the exceptions that a function might throw. However, exception specifications proved problematic in practice, and are deprecated in the C++11 draft standard. We recommend that you don't use **`throw`** exception specifications except for `throw()`, which indicates that the function allows no exceptions to escape. If you must use exception specifications of the deprecated form `throw( type-name )`, MSVC support is limited. For more information, see [Exception Specifications (throw)](exception-specifications-throw-cpp.md). The **`noexcept`** specifier is introduced in C++11 as the preferred alternative to `throw()`. ## See also -[How to: Interface Between Exceptional and Non-Exceptional Code](../cpp/how-to-interface-between-exceptional-and-non-exceptional-code.md)
-[C++ Language Reference](../cpp/cpp-language-reference.md)
+[How to: Interface between exceptional and non-exceptional code](../cpp/how-to-interface-between-exceptional-and-non-exceptional-code.md)
+[C++ language reference](../cpp/cpp-language-reference.md)
[C++ Standard Library](../standard-library/cpp-standard-library-reference.md) diff --git a/docs/cpp/mixing-c-structured-and-cpp-exceptions.md b/docs/cpp/mixing-c-structured-and-cpp-exceptions.md index 2dba7d7d338..3a9c0201b53 100644 --- a/docs/cpp/mixing-c-structured-and-cpp-exceptions.md +++ b/docs/cpp/mixing-c-structured-and-cpp-exceptions.md @@ -1,28 +1,29 @@ --- title: "Mixing C (structured) and C++ exceptions" -ms.date: "08/14/2018" +description: "How to mix structured exception handling and C++ exceptions, and some potential issues." +ms.date: 08/24/2020 helpviewer_keywords: ["exceptions [C++], mixed C and C++", "C++ exception handling, mixed-language", "structured exception handling [C++], mixed C and C++", "catch keyword [C++], mixed", "try-catch keyword [C++], mixed-language"] ms.assetid: a149154e-36dd-4d1a-980b-efde2a563a56 --- # Mixing C (structured) and C++ exceptions -If you want to write portable code, the use of structured exception handling (SEH) in a C++ program isn't recommended. However, you may sometimes want to compile using [/EHa](../build/reference/eh-exception-handling-model.md) and mix structured exceptions and C++ source code, and need some facility for handling both kinds of exceptions. Because a structured exception handler has no concept of objects or typed exceptions, it can't handle exceptions thrown by C++ code. However, C++ **`catch`** handlers can handle structured exceptions. C++ exception handling syntax (**`try`**, **`throw`**, **`catch`**) isn't accepted by the C compiler, but structured exception handling syntax (**__try**, **`__except`**, **`__finally`**) is supported by the C++ compiler. +If you want to write portable code, the use of structured exception handling (SEH) in a C++ program isn't recommended. However, you may sometimes want to compile using [`/EHa`](../build/reference/eh-exception-handling-model.md) and mix structured exceptions and C++ source code, and need some facility for handling both kinds of exceptions. Because a structured exception handler has no concept of objects or typed exceptions, it can't handle exceptions thrown by C++ code. However, C++ **`catch`** handlers can handle structured exceptions. C++ exception handling syntax (**`try`**, **`throw`**, **`catch`**) isn't accepted by the C compiler, but structured exception handling syntax (**`__try`**, **`__except`**, **`__finally`**) is supported by the C++ compiler. -See [_set_se_translator](../c-runtime-library/reference/set-se-translator.md) for information on how to handle structured exceptions as C++ exceptions. +See [`_set_se_translator`](../c-runtime-library/reference/set-se-translator.md) for information on how to handle structured exceptions as C++ exceptions. If you mix structured and C++ exceptions, be aware of these potential issues: -- C++ exceptions and structured exceptions cannot be mixed within the same function. +- C++ exceptions and structured exceptions can't be mixed within the same function. - Termination handlers (**`__finally`** blocks) are always executed, even during unwinding after an exception is thrown. -- C++ exception handling can catch and preserve unwind semantics in all modules compiled with the [/EH](../build/reference/eh-exception-handling-model.md) compiler options, which enable unwind semantics. +- C++ exception handling can catch and preserve the unwind semantics in all modules compiled with the [`/EH`](../build/reference/eh-exception-handling-model.md) compiler options, which enable unwind semantics. -- There may be some situations in which destructor functions are not called for all objects. For example, if a structured exception occurs while attempting to make a function call through an uninitialized function pointer, and that function takes as parameters objects that were constructed before the call, the destructors of those objects are not called during stack unwind. +- There may be some situations in which destructor functions aren't called for all objects. For example, a structured exception could occur while attempting to make a function call through an uninitialized function pointer. If the function parameters are objects constructed before the call, the destructors of those objects don't get called during stack unwind. ## Next steps -- [Using setjmp or longjmp in C++ programs](../cpp/using-setjmp-longjmp.md) +- [Using `setjmp` or `longjmp` in C++ programs](../cpp/using-setjmp-longjmp.md) See more information on the use of `setjmp` and `longjmp` in C++ programs. diff --git a/docs/cpp/restrictions-on-exception-handlers.md b/docs/cpp/restrictions-on-exception-handlers.md index c5fa1895275..2a74a90ce83 100644 --- a/docs/cpp/restrictions-on-exception-handlers.md +++ b/docs/cpp/restrictions-on-exception-handlers.md @@ -1,14 +1,15 @@ --- title: "Restrictions on exception handlers" -ms.date: "11/04/2016" +description: "Describes the restrictions on jumping into structured exception handling blocks." +ms.date: 08/24/2020 helpviewer_keywords: ["restrictions, exception handlers", "exception handling [C++], exception handlers"] ms.assetid: 31d63524-0e8c-419f-b87c-061f4c0ea470 --- # Restrictions on exception handlers -The principal limitation to using exception handlers in code is that you cannot use a **`goto`** statement to jump into a **__try** statement block. Instead, you must enter the statement block through normal flow of control. You can jump out of a **__try** statement block and nest exception handlers as you choose. +The principal limitation to using exception handlers in code is that you can't use a **`goto`** statement to jump into a **`__try`** statement block. Instead, you must enter the statement block through normal flow of control. You can jump out of a **`__try`** statement block, and you can nest exception handlers as you choose. ## See also -[Writing an Exception Handler](../cpp/writing-an-exception-handler.md)
+[Writing an exception handler](../cpp/writing-an-exception-handler.md)
[Structured Exception Handling (C/C++)](../cpp/structured-exception-handling-c-cpp.md) diff --git a/docs/cpp/restrictions-on-termination-handlers.md b/docs/cpp/restrictions-on-termination-handlers.md index 451fbdab63d..2955d7f441c 100644 --- a/docs/cpp/restrictions-on-termination-handlers.md +++ b/docs/cpp/restrictions-on-termination-handlers.md @@ -1,16 +1,17 @@ --- -title: "Restrictions on Termination Handlers" -ms.date: "11/04/2016" +title: "Restrictions on termination handlers" +description: "The restrictions on structured exception handling termination handlers." +ms.date: 08/24/2020 helpviewer_keywords: ["termination handlers [C++], limitations", "restrictions, termination handlers", "try-catch keyword [C++], termination handlers"] ms.assetid: 8b1cb481-303f-4e79-b409-57a002a9fa9e --- # Restrictions on Termination Handlers -You cannot use a **`goto`** statement to jump into a **__try** statement block or a **`__finally`** statement block. Instead, you must enter the statement block through normal flow of control. (You can, however, jump out of a **__try** statement block.) Also, you cannot nest an exception handler or termination handler inside a **`__finally`** block. +You can't use a **`goto`** statement to jump into a **`__try`** statement block or a **`__finally`** statement block. Instead, you must enter the statement block through normal flow of control. (You can, however, jump out of a **`__try`** statement block.) Also, you can't nest an exception handler or termination handler inside a **`__finally`** block. -In addition, some kinds of code permitted in a termination handler produce questionable results, so you should use them with caution, if at all. One is a **`goto`** statement that jumps out of a **`__finally`** statement block. If the block is executing as part of normal termination, nothing unusual happens. But if the system is unwinding the stack, that unwinding stops, and the current function gains control as if there were no abnormal termination. +Some kinds of code permitted in a termination handler produce questionable results, so you should use them with caution, if at all. One is a **`goto`** statement that jumps out of a **`__finally`** statement block. If the block executes as part of normal termination, nothing unusual happens. But if the system is unwinding the stack, that unwinding stops. Then, the current function gains control as if there were no abnormal termination. -A **`return`** statement inside a **`__finally`** statement block presents roughly the same situation. Control returns to the immediate caller of the function containing the termination handler. If the system was unwinding the stack, this process is halted, and the program proceeds as if there had been no exception raised. +A **`return`** statement inside a **`__finally`** statement block presents roughly the same situation. Control returns to the immediate caller of the function that contains the termination handler. If the system was unwinding the stack, this process is halted. Then, the program proceeds as if no exception had been raised. ## See also diff --git a/docs/cpp/structured-exception-handling-c-cpp.md b/docs/cpp/structured-exception-handling-c-cpp.md index d8a711e00bb..ee61d278a80 100644 --- a/docs/cpp/structured-exception-handling-c-cpp.md +++ b/docs/cpp/structured-exception-handling-c-cpp.md @@ -1,28 +1,29 @@ --- title: "Structured Exception Handling (C/C++)" -ms.date: "08/14/2018" +description: "An overview of structured exception handling in Microsoft C/C++." +ms.date: 08/24/2020 helpviewer_keywords: ["termination handlers [C++], handling exceptions in C++", "structured exception handling [C++]", "try-catch keyword [C++], exception handlers", "C++ exception handling, termination handlers", "try-catch keyword [C++], termination handlers", "C++ exception handling, exception handlers"] ms.assetid: dd3b647d-c269-43a8-aab9-ad1458712976 --- # Structured Exception Handling (C/C++) -Structured exception handling (SEH) is a Microsoft extension to C to handle certain exceptional code situations, such as hardware faults, gracefully. Although Windows and Microsoft C++ support SEH, we recommend that you use ISO-standard C++ exception handling because it makes your code more portable and flexible. Nevertheless, to maintain existing code or for particular kinds of programs, you still might have to use SEH. +Structured exception handling (SEH) is a Microsoft extension to C to handle certain exceptional code situations, such as hardware faults, gracefully. Although Windows and Microsoft C++ support SEH, we recommend that you use ISO-standard C++ exception handling. It makes your code more portable and flexible. However, to maintain existing code or for particular kinds of programs, you still might have to use SEH. **Microsoft-specific:** ## Grammar -*try-except-statement* :
-    **__try** *compound-statement* **`__except`** **(** *expression* **)** *compound-statement* - -*try-finally-statement* :
-    **__try** *compound-statement* **`__finally`** *compound-statement* +> *`try-except-statement`* :
+>  **`__try`** *`compound-statement`* **`__except`** **`(`** *`expression`* **`)`** *`compound-statement`* +> +> *`try-finally-statement`* :
+>  **`__try`** *`compound-statement`* **`__finally`** *`compound-statement`* ## Remarks -With SEH, you can ensure that resources such as memory blocks and files are released correctly if execution unexpectedly terminates. You can also handle specific problems—for example, insufficient memory—by using concise structured code that does not rely on **`goto`** statements or elaborate testing of return codes. +With SEH, you can ensure that resources, such as memory blocks and files, get released correctly if execution unexpectedly terminates. You can also handle specific problems—for example, insufficient memory—by using concise structured code that doesn't rely on **`goto`** statements or elaborate testing of return codes. -The try-except and try-finally statements referred to in this article are Microsoft extensions to the C language. They support SEH by enabling applications to gain control of a program after events that would otherwise terminate execution. Although SEH works with C++ source files, it's not specifically designed for C++. If you use SEH in a C++ program that you compile by using the [/EHa or /EHsc](../build/reference/eh-exception-handling-model.md) option, destructors for local objects are called but other execution behavior might not be what you expect. For an illustration, see the example later in this article. In most cases, instead of SEH we recommend that you use ISO-standard [C++ exception handling](../cpp/try-throw-and-catch-statements-cpp.md), which the Microsoft C++ compiler also supports. By using C++ exception handling, you can ensure that your code is more portable, and you can handle exceptions of any type. +The `try-except` and `try-finally` statements referred to in this article are Microsoft extensions to the C language. They support SEH by enabling applications to gain control of a program after events that would otherwise terminate execution. Although SEH works with C++ source files, it's not specifically designed for C++. If you use SEH in a C++ program that you compile by using the [`/EHa` or `/EHsc`](../build/reference/eh-exception-handling-model.md) option, destructors for local objects are called but other execution behavior might not be what you expect. For an illustration, see the example later in this article. In most cases, instead of SEH we recommend that you use ISO-standard [C++ exception handling](../cpp/try-throw-and-catch-statements-cpp.md), which the Microsoft C++ compiler also supports. By using C++ exception handling, you can ensure that your code is more portable, and you can handle exceptions of any type. If you have C code that uses SEH, you can mix it with C++ code that uses C++ exception handling. For information, see [Handle structured exceptions in C++](../cpp/exception-handling-differences.md). @@ -32,7 +33,7 @@ There are two SEH mechanisms: - [Termination handlers](../cpp/writing-a-termination-handler.md), or **`__finally`** blocks, which are always called, whether an exception causes termination or not. -These two kinds of handlers are distinct, but are closely related through a process known as "unwinding the stack." When a structured exception occurs, Windows looks for the most recently installed exception handler that is currently active. The handler can do one of three things: +These two kinds of handlers are distinct, but are closely related through a process known as *unwinding the stack*. When a structured exception occurs, Windows looks for the most recently installed exception handler that's currently active. The handler can do one of three things: - Fail to recognize the exception and pass control to other handlers. @@ -40,9 +41,9 @@ These two kinds of handlers are distinct, but are closely related through a proc - Recognize the exception and handle it. -The exception handler that recognizes the exception may not be in the function that was running when the exception occurred. In some cases, it may be in a function much higher on the stack. The currently running function and all other functions on the stack frame are terminated. During this process, the stack is "unwound;" that is, local non-static variables of terminated functions are cleared from the stack. +The exception handler that recognizes the exception may not be in the function that was running when the exception occurred. It may be in a function much higher on the stack. The currently running function and all other functions on the stack frame are terminated. During this process, the stack is *unwound*. That is, local non-static variables of terminated functions get cleared from the stack. -As it unwinds the stack, the operating system calls any termination handlers that you've written for each function. By using a termination handler, you can clean up resources that otherwise would remain open because of an abnormal termination. If you've entered a critical section, you can exit it in the termination handler. If the program is going to shut down, you can perform other housekeeping tasks such as closing and removing temporary files. +As it unwinds the stack, the operating system calls any termination handlers that you've written for each function. By using a termination handler, you clean up resources that otherwise would remain open because of an abnormal termination. If you've entered a critical section, you can exit it in the termination handler. When the program is going to shut down, you can do other housekeeping tasks such as closing and removing temporary files. ## Next steps @@ -54,7 +55,7 @@ As it unwinds the stack, the operating system calls any termination handlers tha ## Example -As stated earlier, destructors for local objects are called if you use SEH in a C++ program and compile it by using the **/EHa** or **/EHsc** option. However, the behavior during execution may not be what you expect if you are also using C++ exceptions. This example demonstrates these behavioral differences. +As stated earlier, destructors for local objects are called if you use SEH in a C++ program and compile it by using the **`/EHa`** or **`/EHsc`** option. However, the behavior during execution may not be what you expect if you're also using C++ exceptions. This example demonstrates these behavioral differences. ```cpp #include @@ -103,14 +104,14 @@ int main() } ``` -If you use **/EHsc** to compile this code but the local test control macro `CPPEX` is undefined, there is no execution of the `TestClass` destructor and the output looks like this: +If you use **`/EHsc`** to compile this code but the local test control macro `CPPEX` is undefined, the `TestClass` destructor doesn't run. The output looks like this: ```Output Triggering SEH exception Executing SEH __except block ``` -If you use **/EHsc** to compile the code and `CPPEX` is defined by using `/DCPPEX` (so that a C++ exception is thrown), the `TestClass` destructor executes and the output looks like this: +If you use **`/EHsc`** to compile the code and `CPPEX` is defined by using `/DCPPEX` (so that a C++ exception is thrown), the `TestClass` destructor runs, and the output looks like this: ```Output Throwing C++ exception @@ -118,7 +119,7 @@ Destroying TestClass! Executing SEH __except block ``` -If you use **/EHa** to compile the code, the `TestClass` destructor executes regardless of whether the exception was thrown by using `std::throw` or by using SEH to trigger the exception, that is, whether `CPPEX` defined or not. The output looks like this: +If you use **`/EHa`** to compile the code, the `TestClass` destructor executes whether the exception was thrown by using `std::throw` or by using SEH to trigger the exception. That is, whether `CPPEX` is defined or not. The output looks like this: ```Output Throwing C++ exception @@ -126,14 +127,14 @@ Destroying TestClass! Executing SEH __except block ``` -For more information, see [/EH (Exception Handling Model)](../build/reference/eh-exception-handling-model.md). +For more information, see [`/EH` (Exception Handling Model)](../build/reference/eh-exception-handling-model.md). **END Microsoft-specific** ## See also -[Exception Handling](../cpp/exception-handling-in-visual-cpp.md)
+[Exception handling](../cpp/exception-handling-in-visual-cpp.md)
[Keywords](../cpp/keywords-cpp.md)
-[\](../standard-library/exception.md)
-[Errors and Exception Handling](../cpp/errors-and-exception-handling-modern-cpp.md)
+[``](../standard-library/exception.md)
+[Errors and exception handling](../cpp/errors-and-exception-handling-modern-cpp.md)
[Structured Exception Handling (Windows)](/windows/win32/debug/structured-exception-handling) diff --git a/docs/cpp/timing-of-exception-handling-a-summary.md b/docs/cpp/timing-of-exception-handling-a-summary.md index 8a6b5316840..018d7c1ef68 100644 --- a/docs/cpp/timing-of-exception-handling-a-summary.md +++ b/docs/cpp/timing-of-exception-handling-a-summary.md @@ -1,12 +1,13 @@ --- title: "Timing of exception handling: A summary" -ms.date: "05/07/2019" +description: "The timing and order of execution of exception handling in Microsoft C++." +ms.date: 08/24/2020 helpviewer_keywords: ["sequence [C++]", "sequence, of handlers", "exception handling [C++], timing", "setjmpex.h", "termination handlers [C++], timing", "setjmp.h", "handlers [C++], order of exception", "structured exception handling [C++], timing"] ms.assetid: 5d1da546-73fd-4673-aa1a-7ac0f776c420 --- # Timing of exception handling: A summary -A termination handler is executed no matter how the **__try** statement block is terminated. Causes include jumping out of the **__try** block, a `longjmp` statement that transfers control out of the block, and unwinding the stack due to exception handling. +A termination handler is executed no matter how the **`__try`** statement block is terminated. Causes include jumping out of the **`__try`** block, a `longjmp` statement that transfers control out of the block, and unwinding the stack due to exception handling. > [!NOTE] > The Microsoft C++ compiler supports two forms of the `setjmp` and `longjmp` statements. The fast version bypasses termination handling but is more efficient. To use this version, include the file \. The other version supports termination handling as described in the previous paragraph. To use this version, include the file \. The increase in performance of the fast version depends on hardware configuration. @@ -17,15 +18,15 @@ When the cause for interruption is an exception, the system must first execute t 1. An exception is raised. -1. The system looks at the hierarchy of active exception handlers and executes the filter of the handler with highest precedence; this is the exception handler most recently installed and most deeply nested, in terms of blocks and function calls. +1. The system looks at the hierarchy of active exception handlers and executes the filter of the handler with highest precedence. That's the exception handler most recently installed and most deeply nested, going by blocks and function calls. -1. If this filter passes control (returns 0), the process continues until a filter is found that does not pass control. +1. If this filter passes control (returns 0), the process continues until a filter is found that doesn't pass control. 1. If this filter returns -1, execution continues where the exception was raised, and no termination takes place. 1. If the filter returns 1, the following events occur: - - The system unwinds the stack, clearing all stack frames between the currently executing code (where the exception was raised) and the stack frame that contains the exception handler gaining control. + - The system unwinds the stack: It clears all stack frames between where the exception was raised and the stack frame that contains the exception handler. - As the stack is unwound, each termination handler on the stack is executed. diff --git a/docs/cpp/try-except-statement.md b/docs/cpp/try-except-statement.md index 630bd1af1e1..cb344b682e9 100644 --- a/docs/cpp/try-except-statement.md +++ b/docs/cpp/try-except-statement.md @@ -1,29 +1,34 @@ --- title: "try-except statement" description: "The Microsoft C++ reference to the __try and __except structured exception handling statements." -ms.date: "04/03/2020" +ms.date: 08/25/2020 f1_keywords: ["_abnormal_termination_cpp", "_exception_code_cpp", "_exception_info", "__except", "_except", "_exception_code", "__except_cpp", "_exception_info_cpp"] helpviewer_keywords: ["__try keyword [C++]", "EXCEPTION_CONTINUE_EXECUTION macro", "EXCEPTION_CONTINUE_SEARCH macro", "EXCEPTION_EXECUTE_HANDLER macro", "GetExceptionCode function", "try-catch keyword [C++], try-except keyword [C++]", "_exception_code keyword [C++]", "try-except keyword [C++]", "_exception_info keyword [C++]", "_abnormal_termination keyword [C++]"] ms.assetid: 30d60071-ea49-4bfb-a8e6-7a420de66381 --- -# try-except statement +# `try-except` statement -The **try-except** statement is a Microsoft extension that supports structured exception handling in the C and C++ languages. This extension is **Microsoft-specific**. +The `try-except` statement is a **Microsoft-specific** extension that supports structured exception handling in the C and C++ languages. -## Syntax +```cpp + // . . . + __try { + // guarded code + } + __except ( /* filter expression */ ) { + // termination code + } + // . . . +``` + +## Grammar -> **\_\_try**\ -> {\ ->     // guarded code\ -> }\ -> **\_\_except** ( *expression* )\ -> {\ ->     // exception handler code\ -> } +> *`try-except-statement`*:\ +>  **`__try`** *`compound-statement`* **`__except (`** *`expression`* **`)`** *`compound-statement`* ## Remarks -The **try-except** statement is a Microsoft extension to the C and C++ languages. It enables target applications to gain control when events occur that normally terminate program execution. Such events are called *structured exceptions*, or *exceptions* for short. The mechanism that deals with these exceptions is called *structured exception handling* (SEH). +The `try-except` statement is a Microsoft extension to the C and C++ languages. It enables target applications to gain control when events occur that normally terminate program execution. Such events are called *structured exceptions*, or *exceptions* for short. The mechanism that deals with these exceptions is called *structured exception handling* (SEH). For related information, see the [try-finally statement](../cpp/try-finally-statement.md). @@ -32,7 +37,7 @@ Exceptions may be either hardware-based or software-based. Structured exception > [!NOTE] > Structured exception handling works with Win32 for both C and C++ source files. However, it's 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, we recommend you use native C++ exception-handling: [try, catch, and throw](../cpp/try-throw-and-catch-statements-cpp.md) statements. -The compound statement after the **__try** clause is the *body* or *guarded* section. The **`__except`** expression is also known as the *filter* expression. Its value determines how the exception is handled. The compound statement after the **`__except`** clause is the exception handler. The handler specifies the actions to take if an exception is raised during execution of the body section. Execution proceeds as follows: +The compound statement after the **`__try`** clause is the *body* or *guarded* section. The **`__except`** expression is also known as the *filter* expression. Its value determines how the exception is handled. The compound statement after the **`__except`** clause is the exception handler. The handler specifies the actions to take if an exception is raised during execution of the body section. Execution proceeds as follows: 1. The guarded section is executed. @@ -42,7 +47,7 @@ The compound statement after the **__try** clause is the *body* or *guarded* sec - `EXCEPTION_CONTINUE_EXECUTION` (-1) Exception is dismissed. Continue execution at the point where the exception occurred. - - `EXCEPTION_CONTINUE_SEARCH` (0) 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. + - `EXCEPTION_CONTINUE_SEARCH` (0) 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. - `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. @@ -50,19 +55,19 @@ The **`__except`** expression is evaluated as a C expression. It's limited to a Each application can have its own exception handler. -It's not valid to jump into a **__try** statement, but valid to jump out of one. The exception handler isn't called if a process is terminated in the middle of executing a **try-except** statement. +It's not valid to jump into a **`__try`** statement, but valid to jump out of one. The exception handler isn't called if a process is terminated in the middle of executing a `try-except` statement. -For compatibility with previous versions, **_try**, **_except**, and **_leave** are synonyms for **__try**, **`__except`**, and **`__leave`** unless compiler option [/Za \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified. +For compatibility with previous versions, **_try**, **_except**, and **_leave** are synonyms for **`__try`**, **`__except`**, and **`__leave`** unless compiler option [/Za \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified. -### The __leave Keyword +### The `__leave` keyword -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. +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. A **`goto`** statement can also jump out of the guarded section, and it doesn't degrade performance as it does in a **try-finally** statement. That's because stack unwinding doesn't occur. However, we recommend that you use the **`__leave`** keyword rather than a **`goto`** statement. The reason is because you're less likely to make a programming mistake if the guarded section is large or complex. -### Structured Exception Handling Intrinsic Functions +### Structured exception handling intrinsic functions -Structured exception handling provides two intrinsic functions that are available to use with the **try-except** statement: [GetExceptionCode](/windows/win32/Debug/getexceptioncode) and [GetExceptionInformation](/windows/win32/Debug/getexceptioninformation). +Structured exception handling provides two intrinsic functions that are available to use with the `try-except` statement: [GetExceptionCode](/windows/win32/Debug/getexceptioncode) and [GetExceptionInformation](/windows/win32/Debug/getexceptioninformation). `GetExceptionCode` returns the code (a 32-bit integer) of the exception. diff --git a/docs/cpp/try-finally-statement.md b/docs/cpp/try-finally-statement.md index 9a5416dcc7b..a9beb0388cb 100644 --- a/docs/cpp/try-finally-statement.md +++ b/docs/cpp/try-finally-statement.md @@ -1,48 +1,53 @@ --- -title: "try-finally Statement" -ms.date: "11/19/2018" +title: "try-finally statement" +description: "The Microsoft C++ reference to the __try and __finally structured exception handling statements." +ms.date: 08/25/2020 f1_keywords: ["__try", "_try", "__leave_cpp", "__leave", "__finally_cpp", "__try_cpp", "__finally", "_finally"] helpviewer_keywords: ["__try keyword [C++]", "__finally keyword [C++]", "__leave keyword [C++]", "try-catch keyword [C++], try-finally keyword", "try-finally keyword [C++]", "__finally keyword [C++], try-finally statement syntax", "__leave keyword [C++], try-finally statement", "structured exception handling [C++], try-finally"] ms.assetid: 826e0347-ddfe-4f6e-a7bc-0398e0edc7c2 --- -# try-finally Statement +# `try-finally` statement -**Microsoft Specific** +The `try-finally` statement is a **Microsoft-specific** extension that supports structured exception handling in the C and C++ languages. -The following syntax describes the **try-finally** statement: +## Syntax -> **\_\_try**
-> {\ ->     // guarded code\ -> }\ -> **\_\_finally**\ -> {\ ->     // termination code\ -> } +The following syntax describes the `try-finally` statement: + +```cpp + // . . . + __try { + // guarded code + } + __finally { + // termination code + } + // . . . +``` ## Grammar -*try-finally-statement*:
-    **\_\_try** *compound-statement* **\_\_finally** *compound-statement* +> *`try-finally-statement`*:\ +>  **`__try`** *`compound-statement`* **`__finally`** *`compound-statement`* -The **try-finally** statement is a Microsoft extension to the C and C++ languages that enables target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The **try-finally** statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine. +The `try-finally` statement is a Microsoft extension to the C and C++ languages that enable target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The `try-finally` statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine. -For related information and a code sample, see [try-except Statement](../cpp/try-except-statement.md). For more information on structured exception handling in general, see [Structured Exception Handling](../cpp/structured-exception-handling-c-cpp.md). For more information on handling exceptions in managed applications with C++/CLI, see [Exception Handling under /clr](../extensions/exception-handling-cpp-component-extensions.md). +For related information and a code sample, see [`try-except` Statement](../cpp/try-except-statement.md). For more information on structured exception handling in general, see [Structured Exception Handling](../cpp/structured-exception-handling-c-cpp.md). For more information on handling exceptions in managed applications with C++/CLI, see [Exception Handling under `/clr`](../extensions/exception-handling-cpp-component-extensions.md). > [!NOTE] -> 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). +> 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). -The compound statement after the **__try** clause is the guarded section. The compound statement after the **`__finally`** clause is the termination handler. The handler specifies a set of actions that execute when the guarded section is exited, regardless of whether the guarded section is exited by an exception (abnormal termination), or by standard fall through (normal termination). +The compound statement after the **`__try`** clause is the guarded section. The compound statement after the **`__finally`** clause is the termination handler. The handler specifies a set of actions that execute when the guarded section is exited, whether it exits the guarded section by an exception (abnormal termination), or by standard fall through (normal termination). -Control reaches a **__try** statement by simple sequential execution (fall through). When control enters the **__try**, its associated handler becomes active. If the flow of control reaches the end of the try block, execution proceeds as follows: +Control reaches a **`__try`** statement by simple sequential execution (fall through). When control enters the **`__try`**, its associated handler becomes active. If the flow of control reaches the end of the try block, execution proceeds as follows: 1. The termination handler is invoked. -1. When the termination handler completes, execution continues after the **`__finally`** statement. Regardless of how the guarded section ends (for example, via a **`goto`** out of the guarded body or a **`return`** statement), the termination handler is executed *before* the flow of control moves out of the guarded section. +1. When the termination handler completes, execution continues after the **`__finally`** statement. However the guarded section ends (for example, via a **`goto`** out of the guarded body or a **`return`** statement), the termination handler is executed *before* the flow of control moves out of the guarded section. - A **`__finally`** statement does not block searching for an appropriate exception handler. + A **`__finally`** statement doesn't block searching for an appropriate exception handler. -If an exception occurs in the **__try** block, the operating system must find a handler for the exception or the program will fail. If a handler is found, any and all **`__finally`** blocks are executed and execution resumes in the handler. +If an exception occurs in the **`__try`** block, the operating system must find a handler for the exception or the program will fail. If a handler is found, any and all **`__finally`** blocks are executed and execution resumes in the handler. For example, suppose a series of function calls links function A to function D, as shown in the following figure. Each function has one termination handler. If an exception is raised in function D and handled in A, the termination handlers are called in this order as the system unwinds the stack: D, C, B. @@ -50,29 +55,29 @@ For example, suppose a series of function calls links function A to function D, Order of Termination-Handler Execution > [!NOTE] -> The behavior of try-finally is different from some other languages that support the use of **finally**, such as C#. A single **__try** may have either, but not both, of **`__finally`** and **`__except`**. If both are to be used together, an outer try-except statement must enclose the inner try-finally statement. The rules specifying when each block executes are also different. +> The behavior of try-finally is different from some other languages that support the use of **`finally`**, such as C#. A single **`__try`** may have either, but not both, of **`__finally`** and **`__except`**. If both are to be used together, an outer try-except statement must enclose the inner try-finally statement. The rules specifying when each block executes are also different. -For compatibility with previous versions, **_try**, **_finally**, and **_leave** are synonyms for **__try**, **`__finally`**, and **`__leave`** unless compiler option [/Za \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified. +For compatibility with previous versions, **`_try`**, **`_finally`**, and **`_leave`** are synonyms for **`__try`**, **`__finally`**, and **`__leave`** unless compiler option [`/Za` (Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified. ## The __leave Keyword -The **`__leave`** keyword is valid only within the guarded section of a **try-finally** statement, and its effect is to jump to the end of the guarded section. Execution continues at the first statement in the termination handler. +The **`__leave`** keyword is valid only within the guarded section of a `try-finally` statement, and its effect is to jump to the end of the guarded section. Execution continues at the first statement in the termination handler. -A **`goto`** statement can also jump out of the guarded section, but it degrades performance because it invokes stack unwinding. The **`__leave`** statement is more efficient because it does not cause stack unwinding. +A **`goto`** statement can also jump out of the guarded section, but it degrades performance because it invokes stack unwinding. The **`__leave`** statement is more efficient because it doesn't cause stack unwinding. ## Abnormal Termination -Exiting a **try-finally** statement using the [longjmp](../c-runtime-library/reference/longjmp.md) run-time function is considered abnormal termination. It is illegal to jump into a **__try** statement, but legal to jump out of one. All **`__finally`** statements that are active between the point of departure (normal termination of the **__try** block) and the destination (the **`__except`** block that handles the exception) must be run. This is called a local unwind. +Exiting a `try-finally` statement using the [longjmp](../c-runtime-library/reference/longjmp.md) 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. All **`__finally`** statements that are active between the point of departure (normal termination of the **`__try`** block) and the destination (the **`__except`** block that handles the exception) must be run. It's called a *local unwind*. -If a **`try`** block is prematurely terminated for any reason, including a jump out of the block, the system executes the associated **finally** block as a part of the process of unwinding the stack. In such cases, the [AbnormalTermination](/windows/win32/Debug/abnormaltermination) function returns **`true`** if called from within the **finally** block; otherwise, it returns **`false`**. +If a **`__try`** block is prematurely terminated for any reason, including a jump out of the block, the system executes the associated **`__finally`** block as a part of the process of unwinding the stack. In such cases, the [`AbnormalTermination`](/windows/win32/Debug/abnormaltermination) function returns **`true`** if called from within the **`__finally`** block; otherwise, it returns **`false`**. -The termination handler is not called if a process is killed in the middle of executing a **try-finally** statement. +The termination handler isn't called if a process is killed in the middle of executing a `try-finally` statement. -**END Microsoft Specific** +**END Microsoft-specific** ## See also [Writing a termination handler](../cpp/writing-a-termination-handler.md)
[Structured Exception Handling (C/C++)](../cpp/structured-exception-handling-c-cpp.md)
[Keywords](../cpp/keywords-cpp.md)
-[Termination-Handler Syntax](/windows/win32/Debug/termination-handler-syntax) +[Termination-handler syntax](/windows/win32/Debug/termination-handler-syntax) diff --git a/docs/dotnet/exceptions-in-cpp-cli.md b/docs/dotnet/exceptions-in-cpp-cli.md index bbe40fe5301..b0119004fde 100644 --- a/docs/dotnet/exceptions-in-cpp-cli.md +++ b/docs/dotnet/exceptions-in-cpp-cli.md @@ -1,5 +1,6 @@ --- title: "Exceptions in C++/CLI" +description: "Link aggregation page for Microsoft C++/CLI exception handling articles." ms.date: "11/04/2016" ms.assetid: 0010e205-4487-49a9-a8db-4a8ec63cfc83 --- @@ -14,6 +15,6 @@ The articles in this section of the documentation explain exception handling in |[Basic Concepts in Using Managed Exceptions](../dotnet/basic-concepts-in-using-managed-exceptions.md)|Discusses exception handling in managed applications.| |[Differences in Exception Handling Behavior Under /CLR](../dotnet/differences-in-exception-handling-behavior-under-clr.md)|Discusses the differences between standard exception handling and exception handling in C++/CLI.| |[finally](../dotnet/finally.md)|Describes the **`finally`** block that's used to clean up resources that are left after an exception occurs.| -|[How to: Catch Exceptions in Native Code Thrown from MSIL](../dotnet/how-to-catch-exceptions-in-native-code-thrown-from-msil.md)|Demonstrates how to use `__try` and **`__except`** to catch exceptions in native code that are thrown from MSIL.| +|[How to: Catch Exceptions in Native Code Thrown from MSIL](../dotnet/how-to-catch-exceptions-in-native-code-thrown-from-msil.md)|Demonstrates how to use **`__try`** and **`__except`** to catch exceptions in native code that are thrown from MSIL.| |[How to: Define and Install a Global Exception Handler](../dotnet/how-to-define-and-install-a-global-exception-handler.md)|Demonstrates how to capture unhandled exceptions.| |[.NET Programming with C++/CLI (Visual C++)](../dotnet/dotnet-programming-with-cpp-cli-visual-cpp.md)|The top-level article for .NET programming in the Visual C++ documentation.| diff --git a/docs/dotnet/how-to-catch-exceptions-in-native-code-thrown-from-msil.md b/docs/dotnet/how-to-catch-exceptions-in-native-code-thrown-from-msil.md index fa2e993230e..b920aaabab4 100644 --- a/docs/dotnet/how-to-catch-exceptions-in-native-code-thrown-from-msil.md +++ b/docs/dotnet/how-to-catch-exceptions-in-native-code-thrown-from-msil.md @@ -1,16 +1,17 @@ --- -title: "How to: Catch Exceptions in Native Code Thrown from MSIL" +title: "How to: Catch exceptions in native code thrown from MSIL" +description: "Examples of how to catch exceptions in native code thrown from MSIL." ms.date: "11/04/2016" helpviewer_keywords: ["exceptions, catching", "catching exceptions, thrown from MSIL", "MSIL, catching exceptions in native code"] ms.assetid: c15afd2b-8505-43bf-8a4a-f1d41532a124 --- -# How to: Catch Exceptions in Native Code Thrown from MSIL +# How to: Catch exceptions in native code thrown from MSIL -In native code, you can catch native C++ exception from MSIL. You can catch CLR exceptions with `__try` and **`__except`**. +In native code, you can catch native C++ exception from MSIL. You can catch CLR exceptions with **`__try`** and **`__except`**. For more information, see [Structured Exception Handling (C/C++)](../cpp/structured-exception-handling-c-cpp.md) and [Modern C++ best practices for exceptions and error handling](../cpp/errors-and-exception-handling-modern-cpp.md). -## Example +## Example 1 The following sample defines a module with two functions, one that throws a native exception, and another that throws an MSIL exception. @@ -26,7 +27,7 @@ void Test2() { } ``` -## Example +## Example 2 The following sample defines a module that catches a native and MSIL exception. @@ -70,4 +71,4 @@ caught an exception ## See also -[Exception Handling](../extensions/exception-handling-cpp-component-extensions.md) +[Exception handling](../extensions/exception-handling-cpp-component-extensions.md) diff --git a/docs/error-messages/compiler-errors-2/compiler-error-c2702.md b/docs/error-messages/compiler-errors-2/compiler-error-c2702.md index edd0a1cdc83..8ab3ce78de1 100644 --- a/docs/error-messages/compiler-errors-2/compiler-error-c2702.md +++ b/docs/error-messages/compiler-errors-2/compiler-error-c2702.md @@ -1,15 +1,16 @@ --- title: "Compiler Error C2702" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler error C2702." +ms.date: 08/25/2020 f1_keywords: ["C2702"] helpviewer_keywords: ["C2702"] ms.assetid: 6def15d4-9a8d-43e7-ae35-42d7cb57c27e --- # Compiler Error C2702 -__except may not appear in termination block +> `__except` may not appear in termination block -An exception handler (`__try`/**`__except`**) cannot be nested inside a **`__finally`** block. +An exception handler (**`__try`**/**`__except`**) cannot be nested inside a **`__finally`** block. The following sample generates C2702: diff --git a/docs/error-messages/compiler-errors-2/compiler-error-c2703.md b/docs/error-messages/compiler-errors-2/compiler-error-c2703.md index ca93ab88c12..113bf49c705 100644 --- a/docs/error-messages/compiler-errors-2/compiler-error-c2703.md +++ b/docs/error-messages/compiler-errors-2/compiler-error-c2703.md @@ -1,15 +1,20 @@ --- title: "Compiler Error C2703" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler error C2703." +ms.date: 08/24/2020 f1_keywords: ["C2703"] helpviewer_keywords: ["C2703"] ms.assetid: 384295c3-643d-47ae-a9a6-865b3036aa84 --- # Compiler Error C2703 -illegal __leave statement +> illegal `__leave` statement -A **`__leave** statement must be inside a `__try` block. +## Remarks + +A **`__leave`** statement must be inside a **`__try`** block. + +## Example The following sample generates C2703: @@ -24,3 +29,9 @@ int main() { __finally {} } ``` + +## See also + +[The `__leave` keyword](../../cpp/try-except-statement.md#__leave)\ +[`try-except` statement](../../cpp/try-except-statement.md)\ +[`try-finally` statement](../../cpp/try-finally-statement.md) diff --git a/docs/error-messages/compiler-errors-2/compiler-error-c2705.md b/docs/error-messages/compiler-errors-2/compiler-error-c2705.md index 438d4d48fa5..39fdf0029a3 100644 --- a/docs/error-messages/compiler-errors-2/compiler-error-c2705.md +++ b/docs/error-messages/compiler-errors-2/compiler-error-c2705.md @@ -1,15 +1,20 @@ --- title: "Compiler Error C2705" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler error C2705." +ms.date: 08/25/2020 f1_keywords: ["C2705"] helpviewer_keywords: ["C2705"] ms.assetid: 29249ea3-4ea7-4105-944b-bdb83e8d6852 --- # Compiler Error C2705 -'label' : illegal jump into 'exception handler block' scope +> '*label*' : illegal jump into 'exception handler block' scope -Execution jumps to a label within a **`try`**/**`catch`**, `__try`/**`__except`**, `__try`/**`__finally`** block. For more information, see [Exception Handling](../../cpp/exception-handling-in-visual-cpp.md). +## Remarks + +Execution jumps to a label within a **`try`**/**`catch`**, **`__try`**/**`__except`**, or **`__try`**/**`__finally`** block. The compiler doesn't allow this behavior. For more information, see [Exception handling](../../cpp/exception-handling-in-visual-cpp.md). + +## Example The following sample generates C2705: diff --git a/docs/error-messages/compiler-errors-2/compiler-error-c2706.md b/docs/error-messages/compiler-errors-2/compiler-error-c2706.md index f2ee7aa8f35..c21375885ed 100644 --- a/docs/error-messages/compiler-errors-2/compiler-error-c2706.md +++ b/docs/error-messages/compiler-errors-2/compiler-error-c2706.md @@ -1,15 +1,16 @@ --- title: "Compiler Error C2706" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler error C2706." +ms.date: 08/25/2020 f1_keywords: ["C2706"] helpviewer_keywords: ["C2706"] ms.assetid: e18da924-c42d-4b09-8e29-f4e0382d7dc6 --- # Compiler Error C2706 -illegal __except without matching \__try (missing '}' in \__try block?) +> illegal `__except` without matching `__try` (missing '}' in `__try` block?) -The compiler did not find a closing brace for a `__try` block. +The compiler did not find a closing brace for a **`__try`** block. The following sample generates C2706: diff --git a/docs/error-messages/compiler-errors-2/compiler-error-c2712.md b/docs/error-messages/compiler-errors-2/compiler-error-c2712.md index 466ed2929ef..8b1b715cb00 100644 --- a/docs/error-messages/compiler-errors-2/compiler-error-c2712.md +++ b/docs/error-messages/compiler-errors-2/compiler-error-c2712.md @@ -1,17 +1,18 @@ --- title: "Compiler Error C2712" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler error C2712." +ms.date: 08/25/2020 f1_keywords: ["C2712"] helpviewer_keywords: ["C2712"] ms.assetid: f7d4ffcc-7ed2-459b-8067-a728ce647071 --- # Compiler Error C2712 -> cannot use __try in functions that require object unwinding +> cannot use `__try` in functions that require object unwinding ## Remarks -Error C2712 can occur if you use [/EHsc](../../build/reference/eh-exception-handling-model.md), and a function with structured exception handling also has objects that require unwinding (destruction). +Error C2712 can occur if you use [`/EHsc`](../../build/reference/eh-exception-handling-model.md), and a function with structured exception handling also has objects that require unwinding (destruction). Possible solutions: @@ -21,11 +22,11 @@ Possible solutions: - Compile without /EHsc -Error C2712 can also occur if you call a method declared by using the [__event](../../cpp/event.md) keyword. Because the event might be used in a multithreaded environment, the compiler generates code that prevents manipulation of the underlying event object, and then encloses the generated code in an SEH [try-finally statement](../../cpp/try-finally-statement.md). Consequently, error C2712 will occur if you call the event method and pass by value an argument whose type has a destructor. One solution in this case is to pass the argument as a constant reference. +Error C2712 can also occur if you call a method declared by using the [`__event`](../../cpp/event.md) keyword. Because the event might be used in a multithreaded environment, the compiler generates code that prevents manipulation of the underlying event object, and then encloses the generated code in an SEH [`try-finally` statement](../../cpp/try-finally-statement.md). Consequently, error C2712 will occur if you call the event method and pass by value an argument whose type has a destructor. One solution in this case is to pass the argument as a constant reference. -C2712 can also occur if you compile with **/clr:pure** and declare a static array of pointers-to-functions in a `__try` block. A static member requires the compiler to use dynamic initialization under **/clr:pure**, which implies C++ exception handling. However, C++ exception handling is not allowed in a `__try` block. +C2712 can also occur if you compile with **`/clr:pure`** and declare a static array of pointers-to-functions in a **`__try`** block. A static member requires the compiler to use dynamic initialization under **`/clr:pure`**, which implies C++ exception handling. However, C++ exception handling is not allowed in a **`__try`** block. -The **/clr:pure** and **/clr:safe** compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017. +The **`/clr:pure`** and **`/clr:safe`** compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017. ## Example diff --git a/docs/error-messages/compiler-errors-2/compiler-error-c2713.md b/docs/error-messages/compiler-errors-2/compiler-error-c2713.md index 90c88d7c828..59ee0bf0a9e 100644 --- a/docs/error-messages/compiler-errors-2/compiler-error-c2713.md +++ b/docs/error-messages/compiler-errors-2/compiler-error-c2713.md @@ -1,12 +1,13 @@ --- title: "Compiler Error C2713" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler error C2713." +ms.date: 08/25/2020 f1_keywords: ["C2713"] helpviewer_keywords: ["C2713"] ms.assetid: bae9bee3-b4b8-4be5-b6a5-02df587a7278 --- # Compiler Error C2713 -only one form of exception handling permitted per function +> only one form of exception handling permitted per function -You cannot use structured exception handling (`__try`/**`__except`**) and C++ exception handling (**`try`**/**`catch`**) in the same function. +You can't use structured exception handling (**`__try`**/**`__except`**) and C++ exception handling (**`try`**/**`catch`**) in the same function. diff --git a/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4571.md b/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4571.md index 05957e2b764..54845383a3c 100644 --- a/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4571.md +++ b/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4571.md @@ -1,29 +1,30 @@ --- title: "Compiler Warning (level 4) C4571" -ms.date: "11/04/2016" +description: "Documents the Microsoft C++ compiler warning C4571." +ms.date: 08/24/2020 f1_keywords: ["C4571"] helpviewer_keywords: ["C4571"] ms.assetid: 07aa17bd-b15c-4266-824c-57cc445e8edd --- # Compiler Warning (level 4) C4571 -Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught +> Informational: `catch(...)` semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught -C4571 is generated for every catch(...) block when compiling with **/EHs**. +C4571 is generated for every `catch(...)` block when you specify the **`/EHs`** compiler option. -When compiling with **/EHs**, a catch(...) block will not catch a structured exception (divide by zero, null pointer, for example); a catch(...) block will only catch explicitly-thrown, C++ exceptions. For more information, see [Exception Handling](../../cpp/exception-handling-in-visual-cpp.md). +## Remarks -This warning is off by default. Turn this warning on to ensure that when you compile with **/EHs** your catch (...) blocks do not intend to catch structured exceptions. See [Compiler Warnings That Are Off by Default](../../preprocessor/compiler-warnings-that-are-off-by-default.md) for more information. +When you specify the **`/EHs`** compiler option, `catch(...)` blocks don't catch structured exceptions. (Divide by zero, or null pointer exceptions, for example.) A `catch(...)` block only catches explicitly thrown C++ exceptions. For more information, see [Exception Handling](../../cpp/exception-handling-in-visual-cpp.md). -You can resolve C4571 in one of the following ways, +This warning is off by default. Turn this warning on to ensure that when you compile with **`/EHs`** your `catch (...)` blocks don't catch structured exceptions. For more information, see [Compiler warnings that are off by default](../../preprocessor/compiler-warnings-that-are-off-by-default.md). -- Compile with **/EHa** if you still want your catch(...) blocks to catch structured exceptions. +You can resolve C4571 in one of the following ways: -- Do not enable C4571 if you do not want your catch(...) blocks to catch structured exceptions, but you still want to use catch(...) blocks. You can still catch structured exceptions using the structured exception handling keywords (**__try**, **`__except`**, and **`__finally`**). But remember, when compiled **/EHs** destructors will only be called when a C++ exception is thrown, not when an SEH exception occurs. +- Compile with **`/EHa`** if you still want your `catch(...)` blocks to catch structured exceptions. -- Replace catch(...) block with catch blocks for specific C++ exceptions, and optionally, add structured exception handling around the C++ exception handling (**__try**, **`__except`**, and **`__finally`**). See [Structured Exception Handling (C/C++)](../../cpp/structured-exception-handling-c-cpp.md) for more information. +- Don't enable C4571 if you don't want your `catch(...)` blocks to catch structured exceptions, but you still want to use `catch(...)` blocks. You can still catch structured exceptions using the structured exception handling keywords (**`__try`**, **`__except`**, and **`__finally`**). But remember, when compiled using **`/EHs`**, destructors are only called when a C++ exception is thrown, not when an SEH exception occurs. -See [/EH (Exception Handling Model)](../../build/reference/eh-exception-handling-model.md) for more information. +- Replace `catch(...)` blocks with catch blocks for specific C++ exceptions, and optionally, add structured exception handling around the C++ exception handling (**`__try`**, **`__except`**, and **`__finally`**). for more information, see [Structured Exception Handling (C/C++)](../../cpp/structured-exception-handling-c-cpp.md) and [`/EH` (Exception Handling Model)](../../build/reference/eh-exception-handling-model.md). ## Example diff --git a/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4932.md b/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4932.md index ac4d2f713d0..873855d305f 100644 --- a/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4932.md +++ b/docs/error-messages/compiler-warnings/compiler-warning-level-4-c4932.md @@ -1,15 +1,16 @@ --- title: "Compiler Warning (level 4) C4932" -ms.date: "11/04/2016" +description: "Describes Microsoft C/C++ compiler warning C4932." +ms.date: 08/25/2020 f1_keywords: ["C4932"] helpviewer_keywords: ["C4932"] ms.assetid: 0b8d88cc-21f6-45cb-a9f5-1795b7db0dfa --- # Compiler Warning (level 4) C4932 -__identifier(identifier) and \__identifier(identifier) are indistinguishable +> `__identifier(identifier_1)` and `__identifier(identifier_2)` are indistinguishable -The compiler is unable to distinguish between **_finally** and **`__finally`** or `__try` and **_try** as a parameter passed to [__identifier](../../extensions/identifier-cpp-cli.md). You should not attempt to use them both as identifiers in the same program, as it will result in a [C2374](../../error-messages/compiler-errors-1/compiler-error-c2374.md) error. +The compiler is unable to distinguish between **`_finally`** and **`__finally`** or **`__try`** and **`_try`** as a parameter passed to [`__identifier`](../../extensions/identifier-cpp-cli.md). You should not attempt to use them both as identifiers in the same program, as it will result in a [C2374](../../error-messages/compiler-errors-1/compiler-error-c2374.md) error. The following sample generates C4932: