Skip to content

Commit e80b9dd

Browse files
mikeblomeColin Robertson
authored andcommitted
Mb noexcept (#523)
* updated noexcept per user feedback * tweaked wording * tweaked wording per tech review * tweaked wording for declspec(nothrow) per tech review * yet mroe tech rfeview * typo and formatting * added version info * udpated dates and formatting * Lint, fix typo
1 parent 2923800 commit e80b9dd

3 files changed

Lines changed: 157 additions & 150 deletions

File tree

Lines changed: 118 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,135 @@
11
---
22
title: "Exception Specifications (throw) (C++) | Microsoft Docs"
33
ms.custom: ""
4-
ms.date: "11/04/2016"
4+
ms.date: "01/12/2018"
55
ms.reviewer: ""
66
ms.suite: ""
77
ms.technology: ["cpp-language"]
88
ms.tgt_pltfrm: ""
99
ms.topic: "language-reference"
1010
dev_langs: ["C++"]
11-
helpviewer_keywords: ["exceptions [C++], exception specifications", "throwing exceptions [C++], throw keyword", "C++ exception handling [C++], throwing exceptions", "throw keyword [C++], throw() vs. throw(...)", "throw keyword [C++], exception specifications"]
11+
helpviewer_keywords: ["exceptions [C++], exception specifications", "throwing exceptions [C++], throw keyword", "C++ exception handling [C++], throwing exceptions", "throw keyword [C++]", "noexcept keyword [C++]"]
1212
ms.assetid: 4d3276df-6f31-4c7f-8cab-b9d2d003a629
13-
caps.latest.revision: 20
1413
author: "mikeblome"
1514
ms.author: "mblome"
1615
manager: "ghogen"
1716
ms.workload: ["cplusplus"]
1817
---
1918
# Exception Specifications (throw, noexcept) (C++)
20-
Exception specifications are a C++ language feature that indicate the programmer's intent about the exception types that can be propagated by a function. You can specify that a function may or may not exit by an exception by using an *exception specification*. The compiler can use this information to optimize calls to the function, and to terminate the program if an unexpected exception escapes the function. There are two kinds of exception specification. The *noexcept specification* is new in C++11. It specifies whether the set of potential exceptions that can escape the function is empty. The *dynamic exception specification*, or `throw(optional_type_list)` specification, is deprecated in C++11 and is only partially supported by Visual Studio. This exception specification was designed to provide summary information about what exceptions can be thrown out of a function, but in practice it was found to be problematic. The one dynamic exception specification that did prove to be somewhat useful was the unconditional `throw()` specification. For example, the function declaration:
21-
22-
```cpp
23-
void MyFunction(int i) throw();
24-
```
25-
26-
tells the compiler that the function does not throw any exceptions. It is the equivalent to using [__declspec(nothrow)](../cpp/nothrow-cpp.md). Its use is considered optional.
27-
28-
In the ISO C++11 Standard, the [noexcept](../cpp/noexcept-cpp.md) operator was introduced as a replacement. It is supported in Visual Studio 2015 and later. Whenever possible, use a `noexcept` expression to specify whether a function might throw exceptions. For example, use this function declaration instead of the one above:
29-
30-
```cpp
31-
void MyFunction(int i) noexcept;
32-
```
33-
34-
While Visual C++ fully supports the `noexcept` expression, it departs from the ISO C++ Standard in its implementation of dynamic exception specifications. The following table summarizes the Visual C++ implementation of exception specifications:
35-
36-
|Exception specification|Meaning|
37-
|-----------------------------|-------------|
38-
|`noexcept`<br/>`noexcept(true)`<br/>`throw()`|The function does not throw an exception. However, if an exception is thrown out of a function marked `throw()`, the Visual C++ compiler calls `std::terminate`, not `std::unexpected`. See [std::unexpected](../c-runtime-library/reference/unexpected-crt.md) for more information. If a function is marked `noexcept`, `noexcept(true)`, or `throw()`, the Visual C++ compiler assumes that the function does not throw C++ exceptions and generates code accordingly. Because code optimizations might be performed by the C++ compiler based on the assumption that the function does not throw any C++ exceptions, if a function does throw an exception, the program may not execute correctly.|
39-
|`noexcept(false)`<br/>`throw(...)`<br/>No specification|The function can throw an exception of any type.|
40-
|`throw(type)`|The function can throw an exception of type `type`. In Visual C++, this syntax is accepted, but it is interpreted as `noexcept(false)`.|
41-
42-
If exception handling is used in an application, there must be a function in the call stack that handles thrown exceptions before they exit the outer scope of a function marked `noexcept`, `noexcept(true)`, or `throw()`. If any functions called between the one that throws an exception and the one that handles the exception are specified as `noexcept`, `noexcept(true)`, or `throw()`, the program is terminated when the noexcept function propagates the exception.
43-
44-
The exception behavior of a function depends on the following factors:
45-
46-
- Whether you are compiling the function under C or C++.
47-
48-
- Which [/EH](../build/reference/eh-exception-handling-model.md) compiler option you use.
49-
50-
- Whether you explicitly specify the exception specification.
51-
52-
Explicit exception specifications are not allowed on C functions. A C function is assumed not to throw exceptions under **/EHsc**, and may throw structured exceptions under **/EHs**, **/EHa**, or **/EHac**.
53-
54-
The following table summarizes whether a C++ function may potentially throw under various compiler exception handling options:
55-
56-
|Function|/EHsc|/EHs|/EHa|/EHac|
57-
|--------------|------------|-----------|-----------|------------|
58-
|C++ function with no exception specification|Yes|Yes|Yes|Yes|
59-
|C++ function with `noexcept`, `noexcept(true)`, or `throw()` exception specification|No|No|Yes|Yes|
60-
|C++ function with `noexcept(false)`, `throw(...)`, or `throw(type)` exception specification|Yes|Yes|Yes|Yes|
61-
62-
## Example
63-
64-
```cpp
65-
// exception_specification.cpp
66-
// compile with: /EHs
67-
#include <stdio.h>
68-
69-
void handler() {
70-
printf_s("in handler\n");
71-
}
72-
73-
void f1(void) throw(int) {
74-
printf_s("About to throw 1\n");
75-
if (1)
76-
throw 1;
77-
}
78-
79-
void f5(void) throw() {
80-
try {
81-
f1();
82-
}
83-
catch(...) {
84-
handler();
85-
}
86-
}
87-
88-
// invalid, doesn't handle the int exception thrown from f1()
89-
// void f3(void) throw() {
90-
// f1();
91-
// }
92-
93-
void __declspec(nothrow) f2(void) {
94-
try {
95-
f1();
96-
}
97-
catch(int) {
98-
handler();
99-
}
100-
}
101-
102-
// only valid if compiled without /EHc
103-
// /EHc means assume extern "C" functions don't throw exceptions
104-
extern "C" void f4(void);
105-
void f4(void) {
106-
f1();
107-
}
108-
109-
int main() {
110-
f2();
111-
112-
try {
113-
f4();
114-
}
115-
catch(...) {
116-
printf_s("Caught exception from f4\n");
117-
}
118-
f5();
119-
}
120-
```
121-
122-
```Output
123-
About to throw 1
124-
in handler
125-
About to throw 1
126-
Caught exception from f4
127-
About to throw 1
128-
in handler
129-
```
130-
131-
## See Also
132-
[try, throw, and catch Statements (C++)](../cpp/try-throw-and-catch-statements-cpp.md)
19+
20+
Exception specifications are a C++ language feature that indicate the programmer's intent about the exception types that can be propagated by a function. You can specify that a function may or may not exit by an exception by using an *exception specification*. The compiler can use this information to optimize calls to the function, and to terminate the program if an unexpected exception escapes the function.
21+
22+
Prior to C++17 there were two kinds of exception specification. The *noexcept specification* was new in C++11. It specifies whether the set of potential exceptions that can escape the function is empty. The *dynamic exception specification*, or `throw(optional_type_list)` specification, was deprecated in C++11 and removed in C++17, except for `throw()`, which is an alias for noexcept(true). This exception specification was designed to provide summary information about what exceptions can be thrown out of a function, but in practice it was found to be problematic. The one dynamic exception specification that did prove to be somewhat useful was the unconditional `throw()` specification. For example, the function declaration:
23+
24+
```cpp
25+
void MyFunction(int i) throw();
26+
```
27+
28+
tells the compiler that the function does not throw any exceptions. However, in **/std:c++14** mode this could lead to undefined behavior if the function does throw an exception. Therefore we recommend using the [noexcept](../cpp/noexcept-cpp.md) operator instead of the one above:
29+
30+
```cpp
31+
void MyFunction(int i) noexcept;
32+
```
33+
34+
The following table summarizes the Visual C++ implementation of exception specifications:
35+
36+
|Exception specification|Meaning|
37+
|-----------------------------|-------------|
38+
|`noexcept`<br>`noexcept(true)`<br>`throw()`|The function does not throw an exception. In [/std:c++14](../build/reference/std-specify-language-standard-version.md) mode (which is the default), `noexcept` and `noexcept(true)` are equivalent. When an exception is thrown from a function that is declared `noexcept` or `noexcept(true)`, [std::terminate](../standard-library/exception-functions.md#terminate) is invoked. When an exception is thrown from a function declared as `throw()` in **/std:c++14** mode, the result is undefined behavior. No specific function is invoked. This is a divergence from the C++14 standard, which required the compiler to invoke [std::unexpected](../standard-library/exception-functions.md#unexpected). <br> **Visual Studio 2017 version 15.5 and later**: In **/std:c++17** mode , `noexcept`, `noexcept(true)`, and `throw()` are all equivalent. In **/std:c++17** mode, `throw()` is an alias for `noexcept(true)`. In **/std:c++17** mode, when an exception is thrown from a function declared with any of these specifications, [std::terminate](../standard-library/exception-functions.md#terminate) is invoked as required by the C++17 standard.|
39+
|`noexcept(false)`<br/>`throw(...)`<br/>No specification|The function can throw an exception of any type.|
40+
|`throw(type)`| (**C++14 and earlier**) The function can throw an exception of type `type`. The Microsoft C++ compiler accepts the syntax, but interprets it as `noexcept(false)`. In **/std:c++17** mode the compiler issues warning C5040.|
41+
42+
If exception handling is used in an application, there must be a function in the call stack that handles thrown exceptions before they exit the outer scope of a function marked `noexcept`, `noexcept(true)`, or `throw()`. If any functions called between the one that throws an exception and the one that handles the exception are specified as `noexcept`, `noexcept(true)` (or `throw()` in **/std:c++17** mode), the program is terminated when the noexcept function propagates the exception.
43+
44+
The exception behavior of a function depends on the following factors:
45+
46+
- Which [language standard compilation mode](../build/reference/std-specify-language-standard-version.md) is set.
47+
- Whether you are compiling the function under C or C++.
48+
49+
- Which [/EH](../build/reference/eh-exception-handling-model.md) compiler option you use.
50+
51+
- Whether you explicitly specify the exception specification.
52+
53+
Explicit exception specifications are not allowed on C functions. A C function is assumed not to throw exceptions under **/EHsc**, and may throw structured exceptions under **/EHs**, **/EHa**, or **/EHac**.
54+
55+
The following table summarizes whether a C++ function may potentially throw under various compiler exception handling options:
56+
57+
|Function|/EHsc|/EHs|/EHa|/EHac|
58+
|--------------|------------|-----------|-----------|------------|
59+
|C++ function with no exception specification|Yes|Yes|Yes|Yes|
60+
|C++ function with `noexcept`, `noexcept(true)`, or `throw()` exception specification|No|No|Yes|Yes|
61+
|C++ function with `noexcept(false)`, `throw(...)`, or `throw(type)` exception specification|Yes|Yes|Yes|Yes|
62+
63+
## Example
64+
65+
```cpp
66+
// exception_specification.cpp
67+
// compile with: /EHs
68+
#include <stdio.h>
69+
70+
void handler() {
71+
printf_s("in handler\n");
72+
}
73+
74+
void f1(void) throw(int) {
75+
printf_s("About to throw 1\n");
76+
if (1)
77+
throw 1;
78+
}
79+
80+
void f5(void) throw() {
81+
try {
82+
f1();
83+
}
84+
catch(...) {
85+
handler();
86+
}
87+
}
88+
89+
// invalid, doesn't handle the int exception thrown from f1()
90+
// void f3(void) throw() {
91+
// f1();
92+
// }
93+
94+
void __declspec(nothrow) f2(void) {
95+
try {
96+
f1();
97+
}
98+
catch(int) {
99+
handler();
100+
}
101+
}
102+
103+
// only valid if compiled without /EHc
104+
// /EHc means assume extern "C" functions don't throw exceptions
105+
extern "C" void f4(void);
106+
void f4(void) {
107+
f1();
108+
}
109+
110+
int main() {
111+
f2();
112+
113+
try {
114+
f4();
115+
}
116+
catch(...) {
117+
printf_s("Caught exception from f4\n");
118+
}
119+
f5();
120+
}
121+
```
122+
123+
```Output
124+
About to throw 1
125+
in handler
126+
About to throw 1
127+
Caught exception from f4
128+
About to throw 1
129+
in handler
130+
```
131+
132+
## See Also
133+
134+
[try, throw, and catch Statements (C++)](../cpp/try-throw-and-catch-statements-cpp.md)
133135
[C++ Exception Handling](../cpp/cpp-exception-handling.md)

docs/cpp/noexcept-cpp.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "noexcept (C++) | Microsoft Docs"
33
ms.custom: ""
4-
ms.date: "11/04/2016"
4+
ms.date: "01/12/2018"
55
ms.reviewer: ""
66
ms.suite: ""
77
ms.technology: ["cpp-language"]
@@ -32,7 +32,7 @@ ms.workload: ["cplusplus"]
3232
## Remarks
3333
A *noexcept expression* is a kind of *exception specification*, a suffix to a function declaration that represents a set of types that might be matched by an exception handler for any exception that exits a function. Unary conditional operator `noexcept(`*constant_expression*`)` where *constant_expression* yeilds `true`, and its unconditional synonym `noexcept`, specify that the set of potential exception types that can exit a function is empty. That is, the function never throws an exception and never allows an exception to be propagated outside its scope. The operator `noexcept(`*constant_expression*`)` where *constant_expression* yeilds `false`, or the absence of an exception specification (other than for a destructor or deallocation function), indicates that the set of potential exceptions that can exit the function is the set of all types.
3434

35-
Mark a function as `noexcept` only if all the functions that it calls, either directly or indirectly, are also `noexcept` or `const`. The compiler does not necessarily check every code path for exceptions that might bubble up to a `noexcept` function. If an exception does exit the outer scope of a function marked `noexcept`, [std::terminate](../standard-library/exception-functions.md#terminate) is invoked immediately, and there is no guarantee that destructors of any in-scope objects will be invoked. Use `noexcept` instead of the dynamic exception specifier `throw`, which is deprecated in C++11 and later and not fully implemented in Visual Studio. We recommended you apply `noexcept` to any function that never allows an exception to propagate up the call stack. When a function is declared `noexcept`, it enables the compiler to generate more efficient code in several different contexts.
35+
Mark a function as `noexcept` only if all the functions that it calls, either directly or indirectly, are also `noexcept` or `const`. The compiler does not necessarily check every code path for exceptions that might bubble up to a `noexcept` function. If an exception does exit the outer scope of a function marked `noexcept`, [std::terminate](../standard-library/exception-functions.md#terminate) is invoked immediately, and there is no guarantee that destructors of any in-scope objects will be invoked. Use `noexcept` instead of the dynamic exception specifier `throw()`, which is now deprecated in the standard. We recommended you apply `noexcept` to any function that never allows an exception to propagate up the call stack. When a function is declared `noexcept`, it enables the compiler to generate more efficient code in several different contexts. For more information, see [Exception specifications](exception-specifications-throw-cpp.md).
3636

3737
## Example
3838
A template function that copies its argument might be declared `noexcept` on the condition that the object being copied is a plain old data type (POD). Such a function could be declared like this:
@@ -48,5 +48,5 @@ T copy_object(const T& obj) noexcept(std::is_pod<T>)
4848
```
4949
5050
## See Also
51-
[C++ Exception Handling](../cpp/cpp-exception-handling.md)
52-
[Exception Specifications (throw, noexcept)](../cpp/exception-specifications-throw-cpp.md)
51+
[C++ Exception Handling](cpp-exception-handling.md)
52+
[Exception Specifications (throw, noexcept)](exception-specifications-throw-cpp.md)

docs/cpp/nothrow-cpp.md

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "nothrow (C++) | Microsoft Docs"
33
ms.custom: ""
4-
ms.date: "11/04/2016"
4+
ms.date: "01/03/2018"
55
ms.reviewer: ""
66
ms.suite: ""
77
ms.technology: ["cpp-language"]
@@ -11,40 +11,45 @@ f1_keywords: ["nothrow_cpp"]
1111
dev_langs: ["C++"]
1212
helpviewer_keywords: ["__declspec keyword [C++], nothrow", "nothrow __declspec keyword"]
1313
ms.assetid: 0a475139-459c-4ec6-99e8-7ecd0d7f44a3
14-
caps.latest.revision: 7
1514
author: "mikeblome"
1615
ms.author: "mblome"
1716
manager: "ghogen"
1817
ms.workload: ["cplusplus"]
1918
---
2019
# nothrow (C++)
21-
**Microsoft Specific**
22-
23-
A `__declspec` extended attribute which can be used in the declaration of functions.
24-
20+
21+
**Microsoft Specific**
22+
23+
A `__declspec` extended attribute which can be used in the declaration of functions.
24+
2525
## Syntax
2626

27-
```
28-
29-
return-type __declspec(nothrow) [call-convention] function-name ([argument-list])
30-
```
31-
32-
## Remarks
33-
This attribute tells the compiler that the declared function and the functions it calls never throw an exception. With the synchronous exception handling model, now the default, the compiler can eliminate the mechanics of tracking the lifetime of certain unwindable objects in such a function, and significantly reduce the code size. Given the following preprocessor directive, the three function declarations below are equivalent:
34-
35-
```
36-
#define WINAPI __declspec(nothrow) __stdcall
37-
38-
void WINAPI f1();
39-
void __declspec(nothrow) __stdcall f2();
40-
void __stdcall f3() throw();
41-
```
42-
43-
Using `void __declspec(nothrow) __stdcall f2();` has the advantage that you can use an API definition, such as that illustrated by the `#define` statement, to easily specify `nothrow` on a set of functions. The third declaration`, void __stdcall f3() throw();` is the syntax defined by the C++ standard.
44-
45-
46-
**END Microsoft Specific**
47-
48-
## See Also
49-
[__declspec](../cpp/declspec.md)
50-
[Keywords](../cpp/keywords-cpp.md)
27+
> *return-type* __declspec(nothrow) [*call-convention*] *function-name* ([*argument-list*])
28+
29+
## Remarks
30+
31+
We recommend that all new code use the [noexcept](noexcept-cpp.md) operator rather than `__declspec(nothrow)`.
32+
33+
This attribute tells the compiler that the declared function and the functions it calls never throw an exception. However, it does not enforce the directive. In other words, it never causes [std::terminate](../standard-library/exception-functions.md#terminate) to be invoked, unlike `noexcept`, or in **std:c++17** mode (Visual Studio 2017 version 15.5 and later), `throw()`.
34+
35+
With the synchronous exception handling model, now the default, the compiler can eliminate the mechanics of tracking the lifetime of certain unwindable objects in such a function, and significantly reduce the code size. Given the following preprocessor directive, the three function declarations below are equivalent in **/std:c++14** mode:
36+
37+
```cpp
38+
#define WINAPI __declspec(nothrow) __stdcall
39+
40+
void WINAPI f1();
41+
void __declspec(nothrow) __stdcall f2();
42+
void __stdcall f3() throw();
43+
```
44+
45+
In **/std:c++17** mode, `throw()` is not equivalent to the others that use `__declspec(nothrow)` because it causes `std::terminate` to be invoked if an exception is thrown from the function.
46+
47+
The `void __stdcall f3() throw();` declaration uses the syntax defined by the C++ standard. In C++17 the `throw()` keyword was deprecated.
48+
49+
**END Microsoft Specific**
50+
51+
## See also
52+
53+
[__declspec](../cpp/declspec.md)
54+
[noexcept](noexcept-cpp.md)
55+
[Keywords](../cpp/keywords-cpp.md)

0 commit comments

Comments
 (0)