Difference between revisions of "cpp/language/noexcept"
D41D8CD98F (Talk | contribs) (I don't think it is a misspelling, link value category to explanation prvalue) |
m (→Keywords: −usage −rev) |
||
(16 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
− | {{title|noexcept operator {{mark since c++11}}}} | + | {{title|{{tt|noexcept}} operator {{mark since c++11}}}} |
− | {{cpp/language/exceptions/navbar}} | + | {{cpp/language/expressions/exceptions/navbar}} |
− | The {{ | + | The {{c/core|noexcept}} operator performs a compile-time check that returns {{c|true}} if an expression is declared to not throw any exceptions. |
− | It can be used within a function template's {{rlp| | + | It can be used within a function template's {{rlp|noexcept spec|{{c/core|noexcept}} specifier}} to declare that the function will throw exceptions for some types but not others. |
===Syntax=== | ===Syntax=== | ||
− | |||
{{sdsc begin}} | {{sdsc begin}} | ||
− | {{sdsc | {{ttb|noexcept(}} {{spar|expression}} {{ttb|)}}}} | + | {{sdsc|{{ttb|noexcept(}} {{spar|expression}} {{ttb|)}}}} |
{{sdsc end}} | {{sdsc end}} | ||
− | Returns a {{ | + | Returns a {{rlpsd|value category#prvalue}} of type {{c/core|bool}}. The result is {{c|true}} if {{rev inl|until=c++17|the set of {{rlp|except spec|potential exceptions}} of the {{spar|expression}} is empty}}{{rev inl|since=c++17|{{spar|expression}} is specified to be {{rlp|noexcept spec|non-throwing}}}}, and {{c|false}} otherwise. |
− | + | {{spar|expression}} is an {{rlp|expressions#Potentially-evaluated expressions|unevaluated operand}}. | |
− | + | {{rrev|since=c++17| | |
+ | If {{spar|expression}} is a prvalue, {{rlpsd|implicit conversion#Temporary materialization}} is applied. | ||
+ | }} | ||
− | + | ===Notes=== | |
− | + | Even if {{c|noexcept(expr)}} is {{c|true}}, an evaluation of {{c|expr}} may still throw as the result of encountering undefined behavior. | |
− | + | ||
− | + | ||
− | + | {{rrev|since=c++17| | |
+ | If {{spar|expression}} is of a class type or (possibly multidimensional) array thereof, temporary materialization requires the destructor be non-deleted and accessible. | ||
+ | }} | ||
===Keywords=== | ===Keywords=== | ||
− | |||
{{ltt|cpp/keyword/noexcept}} | {{ltt|cpp/keyword/noexcept}} | ||
===Example=== | ===Example=== | ||
{{example | {{example | ||
− | + | |code= | |
#include <iostream> | #include <iostream> | ||
#include <utility> | #include <utility> | ||
Line 40: | Line 40: | ||
auto lmay_throw = []{}; | auto lmay_throw = []{}; | ||
auto lno_throw = []() noexcept {}; | auto lno_throw = []() noexcept {}; | ||
− | class T{ | + | |
+ | class T | ||
+ | { | ||
public: | public: | ||
− | + | ~T(){} // dtor prevents move ctor | |
− | + | // copy ctor is noexcept | |
}; | }; | ||
− | class U{ | + | |
+ | class U | ||
+ | { | ||
public: | public: | ||
− | + | ~U(){} // dtor prevents move ctor | |
− | + | // copy ctor is noexcept(false) | |
− | + | std::vector<int> v; | |
}; | }; | ||
− | class V{ | + | |
+ | class V | ||
+ | { | ||
public: | public: | ||
− | + | std::vector<int> v; | |
}; | }; | ||
− | + | ||
int main() | int main() | ||
{ | { | ||
− | + | T t; | |
− | + | U u; | |
− | + | V v; | |
− | + | ||
− | + | std::cout << std::boolalpha << | |
− | + | "may_throw() is noexcept(" << noexcept(may_throw()) << ")\n" | |
− | + | "no_throw() is noexcept(" << noexcept(no_throw()) << ")\n" | |
− | + | "lmay_throw() is noexcept(" << noexcept(lmay_throw()) << ")\n" | |
− | + | "lno_throw() is noexcept(" << noexcept(lno_throw()) << ")\n" | |
− | + | "~T() is noexcept(" << noexcept(std::declval<T>().~T()) << ")\n" | |
− | + | // note: the following tests also require that ~T() is noexcept because | |
− | + | // the expression within noexcept constructs and destroys a temporary | |
− | + | "T(rvalue T) is noexcept(" << noexcept(T(std::declval<T>())) << ")\n" | |
− | + | "T(lvalue T) is noexcept(" << noexcept(T(t)) << ")\n" | |
− | + | "U(rvalue U) is noexcept(" << noexcept(U(std::declval<U>())) << ")\n" | |
− | + | "U(lvalue U) is noexcept(" << noexcept(U(u)) << ")\n" | |
+ | "V(rvalue V) is noexcept(" << noexcept(V(std::declval<V>())) << ")\n" | ||
+ | "V(lvalue V) is noexcept(" << noexcept(V(v)) << ")\n"; | ||
} | } | ||
|output= | |output= | ||
− | + | may_throw() is noexcept(false) | |
− | + | no_throw() is noexcept(true) | |
− | + | lmay_throw() is noexcept(false) | |
− | + | lno_throw() is noexcept(true) | |
− | + | ~T() is noexcept(true) | |
− | + | T(rvalue T) is noexcept(true) | |
− | + | T(lvalue T) is noexcept(true) | |
− | + | U(rvalue U) is noexcept(false) | |
− | + | U(lvalue U) is noexcept(false) | |
− | + | V(rvalue V) is noexcept(true) | |
− | + | V(lvalue V) is noexcept(false) | |
}} | }} | ||
+ | |||
+ | ===Defect reports=== | ||
+ | {{dr list begin}} | ||
+ | {{dr list item|wg=cwg|dr=2722|std=C++17|before=it was unclear whether temporary materialization<br>is applied if {{spar|expression}} is a prvalue|after=it is applied<br>in this case}} | ||
+ | {{dr list item|wg=cwg|dr=2792|std=C++11|before=the {{c/core|noexcept}} operator was required to determine whether exceptions<br>may be thrown in the case of encountering undefined behavior|after=not required}} | ||
+ | {{dr list end}} | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/language/dsc | + | {{dsc inc|cpp/language/dsc noexcept spec}} |
− | {{dsc inc | cpp/language/dsc | + | {{dsc inc|cpp/language/dsc except spec}} |
{{dsc end}} | {{dsc end}} | ||
− | + | {{langlinks|de|es|fr|it|ja|pt|ru|zh}} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + |
Latest revision as of 15:44, 12 August 2024
The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions.
It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.
Contents |
[edit] Syntax
noexcept( expression )
|
|||||||||
Returns a prvalue of type bool. The result is true if the set of potential exceptions of the expression is empty(until C++17)expression is specified to be non-throwing(since C++17), and false otherwise.
expression is an unevaluated operand.
If expression is a prvalue, temporary materialization is applied. |
(since C++17) |
[edit] Notes
Even if noexcept(expr) is true, an evaluation of expr may still throw as the result of encountering undefined behavior.
If expression is of a class type or (possibly multidimensional) array thereof, temporary materialization requires the destructor be non-deleted and accessible. |
(since C++17) |
[edit] Keywords
[edit] Example
#include <iostream> #include <utility> #include <vector> void may_throw(); void no_throw() noexcept; auto lmay_throw = []{}; auto lno_throw = []() noexcept {}; class T { public: ~T(){} // dtor prevents move ctor // copy ctor is noexcept }; class U { public: ~U(){} // dtor prevents move ctor // copy ctor is noexcept(false) std::vector<int> v; }; class V { public: std::vector<int> v; }; int main() { T t; U u; V v; std::cout << std::boolalpha << "may_throw() is noexcept(" << noexcept(may_throw()) << ")\n" "no_throw() is noexcept(" << noexcept(no_throw()) << ")\n" "lmay_throw() is noexcept(" << noexcept(lmay_throw()) << ")\n" "lno_throw() is noexcept(" << noexcept(lno_throw()) << ")\n" "~T() is noexcept(" << noexcept(std::declval<T>().~T()) << ")\n" // note: the following tests also require that ~T() is noexcept because // the expression within noexcept constructs and destroys a temporary "T(rvalue T) is noexcept(" << noexcept(T(std::declval<T>())) << ")\n" "T(lvalue T) is noexcept(" << noexcept(T(t)) << ")\n" "U(rvalue U) is noexcept(" << noexcept(U(std::declval<U>())) << ")\n" "U(lvalue U) is noexcept(" << noexcept(U(u)) << ")\n" "V(rvalue V) is noexcept(" << noexcept(V(std::declval<V>())) << ")\n" "V(lvalue V) is noexcept(" << noexcept(V(v)) << ")\n"; }
Output:
may_throw() is noexcept(false) no_throw() is noexcept(true) lmay_throw() is noexcept(false) lno_throw() is noexcept(true) ~T() is noexcept(true) T(rvalue T) is noexcept(true) T(lvalue T) is noexcept(true) U(rvalue U) is noexcept(false) U(lvalue U) is noexcept(false) V(rvalue V) is noexcept(true) V(lvalue V) is noexcept(false)
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 2722 | C++17 | it was unclear whether temporary materialization is applied if expression is a prvalue |
it is applied in this case |
CWG 2792 | C++11 | the noexcept operator was required to determine whether exceptions may be thrown in the case of encountering undefined behavior |
not required |
[edit] See also
noexcept specifier(C++11)
|
specifies whether a function could throw exceptions |
Dynamic exception specification(until C++17) | specifies what exceptions are thrown by a function (deprecated in C++11) |