Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/noexcept"

From cppreference.com
< cpp‎ | language
(c++17)
m (Keywords: −usage −rev)
 
(15 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 {{tt|noexcept}} operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions.
+
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 | noexcept specifier}} to declare that the function will throw exceptions for some types but not others.
+
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 {{rlp|value category|prvalue}} of type {{c|bool}}.  
+
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.
  
===Explanation===
+
{{spar|expression}} is an {{rlp|expressions#Potentially-evaluated expressions|unevaluated operand}}.
  
The {{tt|noexcept}} operator does not evaluate {{spar|expression}}.
+
{{rrev|since=c++17|
 
+
If {{spar|expression}} is a prvalue, {{rlpsd|implicit conversion#Temporary materialization}} is applied.
{{rev begin}}
+
}}
{{rev|until=c++17|
+
The result is {{ttb|false}} if the {{spar|expression}} contains at least one of the following potentially evaluated constructs:
+
  
:* call to any type of function that does not have non-throwing exception specification, unless it is a {{rlp|constexpr | constant expression}}.
+
===Notes===
:* {{rlp|throw|{{tt|throw}} expression}}.
+
Even if {{c|noexcept(expr)}} is {{c|true}}, an evaluation of {{c|expr}} may still throw as the result of encountering undefined behavior.
:* {{rlp|dynamic_cast|{{tt|dynamic_cast}} expression}} when the target type is a reference type, and conversion needs a run time check
+
:* {{rlp|typeid|{{tt|typeid}} expression}} when argument type is polymorphic class type
+
  
In 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.
 
}}
 
}}
{{rev|since=c++17|
+
 
The result is {{ttb|true}} if the set of {{rlp|except spec|''potential exceptions''}} of the {{spar|expression}} is empty, and {{ttb|false}} otherwise.
+
}}
+
{{rev end}}
+
 
===Keywords===
 
===Keywords===
 
 
{{ltt|cpp/keyword/noexcept}}
 
{{ltt|cpp/keyword/noexcept}}
  
 
===Example===
 
===Example===
 
{{example
 
{{example
| code=
+
|code=
 
#include <iostream>
 
#include <iostream>
 
#include <utility>
 
#include <utility>
Line 48: 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
+
    ~T(){} // dtor prevents move ctor
        // copy ctor is noexcept
+
          // copy ctor is noexcept
 
};
 
};
class U{
+
 
 +
class U
 +
{
 
public:
 
public:
  ~U(){} // dtor prevents move ctor
+
    ~U(){} // dtor prevents move ctor
        // copy ctor is noexcept(false)
+
          // copy ctor is noexcept(false)
  std::vector<int> v;
+
    std::vector<int> v;
 
};
 
};
class V{
+
 
 +
class V
 +
{
 
public:
 
public:
  std::vector<int> v;
+
    std::vector<int> v;
 
};
 
};
+
 
 
int main()
 
int main()
 
{
 
{
T t;
+
    T t;
U u;
+
    U u;
V v;
+
    V v;
+
   
std::cout << std::boolalpha
+
    std::cout << std::boolalpha <<
            << "Is may_throw() noexcept? " << noexcept(may_throw()) << '\n'
+
        "may_throw() is noexcept(" << noexcept(may_throw()) << ")\n"
            << "Is no_throw() noexcept? " << noexcept(no_throw()) << '\n'
+
        "no_throw() is noexcept(" << noexcept(no_throw()) << ")\n"
            << "Is lmay_throw() noexcept? " << noexcept(lmay_throw()) << '\n'
+
        "lmay_throw() is noexcept(" << noexcept(lmay_throw()) << ")\n"
            << "Is lno_throw() noexcept? " << noexcept(lno_throw()) << '\n'
+
        "lno_throw() is noexcept(" << noexcept(lno_throw()) << ")\n"
            << "Is ~T() noexcept? " << noexcept(std::declval<T>().~T()) << '\n'
+
        "~T() is noexcept(" << noexcept(std::declval<T>().~T()) << ")\n"
            << "Is T(rvalue T) noexcept? " << noexcept(T(std::declval<T>())) << '\n'
+
        // note: the following tests also require that ~T() is noexcept because
            << "Is T(lvalue T) noexcept? " << noexcept(T(t)) << '\n'
+
        // the expression within noexcept constructs and destroys a temporary
            << "Is U(rvalue U) noexcept? " << noexcept(U(std::declval<U>())) << '\n'
+
        "T(rvalue T) is noexcept(" << noexcept(T(std::declval<T>())) << ")\n"
            << "Is U(lvalue U) noexcept? " << noexcept(U(u)) << '\n
+
        "T(lvalue T) is noexcept(" << noexcept(T(t)) << ")\n"
            << "Is V(rvalue V) noexcept? " << noexcept(V(std::declval<V>())) << '\n'
+
        "U(rvalue U) is noexcept(" << noexcept(U(std::declval<U>())) << ")\n"
            << "Is V(lvalue V) noexcept? " << noexcept(V(v)) << '\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=
Is may_throw() noexcept? false
+
may_throw() is noexcept(false)
Is no_throw() noexcept? true
+
no_throw() is noexcept(true)
Is lmay_throw() noexcept? false
+
lmay_throw() is noexcept(false)
Is lno_throw() noexcept? true
+
lno_throw() is noexcept(true)
Is ~T() noexcept? true
+
~T() is noexcept(true)
Is T(rvalue T) noexcept? true
+
T(rvalue T) is noexcept(true)
Is T(lvalue T) noexcept? true
+
T(lvalue T) is noexcept(true)
Is U(rvalue U) noexcept? false
+
U(rvalue U) is noexcept(false)
Is U(lvalue U) noexcept? false
+
U(lvalue U) is noexcept(false)
Is V(rvalue V) noexcept? true
+
V(rvalue V) is noexcept(true)
Is V(lvalue V) noexcept? false
+
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 noexcept_spec}}
+
{{dsc inc|cpp/language/dsc noexcept spec}}
{{dsc inc | cpp/language/dsc except_spec}}
+
{{dsc inc|cpp/language/dsc except spec}}
 
{{dsc end}}
 
{{dsc end}}
  
[[de:cpp/language/noexcept]]
+
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
[[es:cpp/language/noexcept]]
+
[[fr:cpp/language/noexcept]]
+
[[it:cpp/language/noexcept]]
+
[[ja:cpp/language/noexcept]]
+
[[pt:cpp/language/noexcept]]
+
[[ru:cpp/language/noexcept]]
+
[[zh:cpp/language/noexcept]]
+

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]