Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/noexcept"

From cppreference.com
< cpp‎ | language
(Explanation: fix link)
m (Keywords: −usage −rev)
 
(45 intermediate revisions by 16 users not shown)
Line 1: Line 1:
{{title|noexcept operator {{mark c++11 feature}}}}
+
{{title|{{tt|noexcept}} operator {{mark since c++11}}}}
{{cpp/language/sidebar}}
+
{{cpp/language/expressions/exceptions/navbar}}
Checks whether the evaluation of an expression can throw an exception
+
  
Used within {{rlp|noexcept_spec | noexcept specifier}} when the fact if the function can throw depends on template parameters.
+
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|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|{{ttb|noexcept(}} {{spar|expression}} {{ttb|)}}}}
 +
{{sdsc end}}
  
{{sdcl list begin}}
+
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.
{{sdcl list item | {{ttb|noexcept(}} {{sparam|expression}} {{ttb|)}}}}
+
{{sdcl list end}}
+
  
Returns an object of type {{cpp|bool}}.  
+
{{spar|expression}} is an {{rlp|expressions#Potentially-evaluated expressions|unevaluated operand}}.
  
===Explanation===
+
{{rrev|since=c++17|
 +
If {{spar|expression}} is a prvalue, {{rlpsd|implicit conversion#Temporary materialization}} is applied.
 +
}}
  
The {{tt|noexcept}} operator does not evaluate {{sparam|expression}}. The result is {{ttb|false}} if the {{sparam|expression}} contains at least one of the following potentially evaluated constructs:
+
===Notes===
:* call to any type of function, which does not have non-throwing exception specification, unless it is a {{rlp|constexpr | constant expression}}.
+
Even if {{c|noexcept(expr)}} is {{c|true}}, an evaluation of {{c|expr}} may still throw as the result of encountering undefined behavior.
:* {{rlpt|throw}} expression
+
:* {{rlpt|dynamic_cast}} expression when the conversion needs a run time check
+
:* {{rlpt|typeid}} expression when argument type is polymorphic class type
+
  
On all other cases the result is {{ttb|true}}
+
{{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/keywords/noexcept}}
+
  
 
===Example===
 
===Example===
{{example cpp
+
{{example
| code=
+
|code=
template <typename T>
+
#include <iostream>
void self_assign(T& t) noexcept(noexcept(T::operator=))  
+
#include <utility>
{ // self_assign is noexcept if and only if T::operator= is noexcept
+
#include <vector>
    t = t;
+
 
}  
+
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)
 
}}
 
}}
  
 +
===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===
{{rlp|noexcept_spec | {{tt|noexcept}} specifier}}, {{rlp|throw_spec | exception specifications}}
+
{{dsc begin}}
 +
{{dsc inc|cpp/language/dsc noexcept spec}}
 +
{{dsc inc|cpp/language/dsc except spec}}
 +
{{dsc end}}
 +
 
 +
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Latest revision as of 15:44, 12 August 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 
Exceptions
try block
Throwing exceptions
Handling exceptions
Exception specification
    noexcept specification (C++11)
    dynamic specification (until C++17*)
noexcept operator (C++11)
 

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

noexcept

[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[edit]
Dynamic exception specification(until C++17) specifies what exceptions are thrown by a function (deprecated in C++11) [edit]