<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>

<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">

<style type="text/css">

body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

</style>

<title>Removing Deprecated Exception Specifications from C++17</title>
</head>

<body>

<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P0003R0</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2015-09-28</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>


<h1>Removing Deprecated Exception Specifications from C++17</h1>

<h2>Table of Contents</h2>
<ul>
<li><a href="#1.0">Introduction</a></li>
<li><a href="#2.0">A Brief History of Exception Specifications</a></li>
<li><a href="#3.0">Proposed Changes</a></li>
<li><a href="#4.0">Motivation for Change</a></li>
<li><a href="#5.0">Compatibility Concerns</a></li>
<li><a href="#6.0">Proposed Wording</a></li>
<ul>
  <li><a href="#STD_3.3.7">3.3.7 Class scope [basic.scope.class]</a></li>
  <li><a href="#STD_3.4.1">3.4.1 Unqualified name lookup [basic.lookup.unqual]</a></li>
  <li><a href="#STD_8.4.2">8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]</a></li>
  <li><a href="#STD_9.2">9.2 Class members [class.mem]</a></li>
  <li><a href="#STD_14.5">14.5 Template declarations [temp.decls]</a></li>
  <li><a href="#STD_14.5.3">14.5.3 Variadic templates [temp.variadic]</a></li>
  <li><a href="#STD_14.6">14.6 Name resolution [temp.res]</a></li>
  <li><a href="#STD_14.6.4.1">14.6.4.1 Point of instantiation [temp.point]</a></li>
  <li><a href="#STD_14.7.1">14.7.1 Implicit instantiation [temp.inst]</a></li>
  <li><a href="#STD_14.7.2">14.7.2 Explicit instantiation [temp.explicit]</a></li>
  <li><a href="#STD_14.8.2">14.8.2 Template argument deduction [temp.deduct]</a></li>
  <li><a href="#STD_15.4">15.4 Exception specifications [except.spec]</a></li>
  <li><a href="#STD_15.5">15.5 Special functions [except.special]</a></li>
  <ul>
    <li><a href="#STD_15.5.1">15.5.1 The std::terminate() function [except.terminate]</a></li>
    <li><a href="#STD_15.5.2">15.5.2 The <tt>std::unexpected()</tt> function [except.unexpected]</a></li>
  </ul>
  <li><a href="#STD_17.6.5.12">17.6.5.12 Restrictions on exception handling [res.on.exception.handling]</a></li>
  <li><a href="#STD_18.8">18.8 Exception Handling [support.exception]</a></li>
  <ul>
    <li><a href="#STD_18.8_synopsis">Header &lt;exception&gt; synopsis</a></li>
    <li><a href="#STD_18.8.2">18.8.2 Class <tt>bad_exception</tt> [bad.exception]</a></li>
  </ul>
  <li><a href="#STD_23.3.2.8">23.3.2.8 Zero sized arrays [array.zero]</a></li>
  <li><a href="#STD_B">Annex B (informative) Implementation quantities [implimits]</a></li>
  <li><a href="#STD_D.4">D.4 Dynamic exception specifications [depr.except.spec]</a></li>
  <li><a href="#STD_D.8">D.8 Violating <i>exception-specifications</i> [exception.unexpected]</a></li>
  <ul>
    <li><a href="#STD_D.8.1">D.8.1 Type <tt>unexpected_handler</tt> [unexpected.handler]</a></li>
    <li><a href="#STD_D.8.2">D.8.2 <tt>set_unexpected</tt> [set.unexpected]</a></li>
    <li><a href="#STD_D.8.3">D.8.3 <tt>get_unexpected</tt> [get.unexpected]</a></li>
    <li><a href="#STD_D.8.4">D.8.4 <tt>unexpected</tt> [unexpected]</a></li>
  </ul>
</ul>
<li><a href="#7.0">Acknowledgements</a></li>
<li><a href="#8.0">References</a></li>
</ul>


<h2><a name="1.0">Introduction</a></h2>
<p>
Dynamic exception specifications were deprecated in C++11.  This paper formally
proposes removing the feature from C++17, while retaining the (still) deprecated
<tt>throw()</tt> specification strictly as an alias for <tt>noexcept(true)</tt>.
</p>


<h2><a name="2.0">A Brief History of Exception Specifications</a></h2>
<p>
Exception specifications were added as part of the original design of the exception
language feature.  However, the experience of using them was less than desired, with
the general consensus by the time the 1998 standard was published being, generally,
to not use them.  The standard library made the explicit choice to not use exception
specifications apart from a handful of places where guaranteeing an empty
(no-throwing) specification seemed useful.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0741.htm">N741</a>
gives a brief summary of the LWG thoughts at the time.
</p>
<p>
By the time C++11 was published, the feeling against exception specifications had
grown, the limited real-world use generally reported negative user experience, and
the language feature, renamed as <i>dynamic</i> exception specifcations, was
deprecated,
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html">N3051</a>).
A new languge feature, <tt>noexcept</tt>, was introduced to describe the important
case of knowing when a function could guarantee to not throw any exceptions.
</p>
<p>
Looking ahead to C++17, there is a desire to incorporate exception specifications
into the type system,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4533.html">N4533</a>.
This solves a number of awkward corners that arise from exception specifications not
being part of the type of a function, but still does nothing for the case of deprecated
dynamic exception specifications, so the actual language does not get simpler, and we
must still document and teach the awkwards corners that arise from dynamic exception
specifications outside the type system.
</p>



<h2><a name="3.0">Proposed Changes</a></h2>
<p>
The recommendation of this paper is to remove dynamic exception specifications from
the language.  However, the syntax of the <tt>throw()</tt> specification should be
retained, but no longer as a dyanmic exception specification.  Its meaning should
become strictly an alias for <tt>noexcept(true)</tt>, and its usage should remain
deprecated.
</p>
<p>
To minimize the impact on the current standard wording, the grammar term
<i>exception-specification</i> is retained, although it has only one production
and could be replaced entirely with <i>noexcept-specification</i>.  Alternatively,
the grammar term <i>noexcept-specification</i> could be retired.
</p>
<p>
The wording changes in this initial proposal are deliberately minimal in an effort to
ensure the least risk of accidental change.  However, rather than using the language
of sets of compatible exception specifications (where there are now only two such sets,
the empty set and the set of all types) it would be possible to write a simpler, clearer
form describing instead functions that permit exceptions, and functions that permit <i>no</i>
exceptions.  While such a specification would be preferred, it is also beyond the drafting
skills of the proposal author.
</p>
<p>
The redrafting goes slightly beyond minimal by eliminating use of the pseudo-type &quot;any&quot;.
This change, while improving clarity, also avoids confusion with the standard library type
<tt>any</tt> from the Library Fundamentals TS in the event that it becomes part of a future
standard library.
</p>


<h2><a name="4.0">Motivation for Change</a></h2>
<p>
Dynamic exception specifications are a failed experiment, but this is not immediately clear to
novices, especially where the "novice" is an experienced developer coming from other languages
such as Java, where exception specifications may be more widely used.  Their continuing
presence, especially in an important part of the languge model (exceptions are key to understanding
constructors, destructors, and RAII) is an impediment that must be explained.  It remains
embarassing to explain to new developers that there are features of the language that conforming
compilers are required to support, yet should never be used.
</p>
<p>
Exception specifications in general occupy an awkward corner of the grammer, where they do not
affect the type system, yet critically affect how a virtual function can be overridden, or which
functions can bind to certain function pointer variables.  As noted above,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4533">N4533</a> would go a long
way to resolving that problem for <tt>noexcept</tt> exception specifications, which makes the hole
left for dynamic exception specifications even more awkward and unusual for the next generation of
C++ developers. 
</p>
<p>
C++17 is on schedule to be a release with several breaking changes for old code, with the standard
library removing <tt>auto_ptr</tt>, the classic C++98 fuction binders, and more.  Similarly, it is
expected that the core language will lose trigraphs, the <tt>register</tt> keyword, and the
increment operator for <tt>bool</tt>.  This would be a good time to make a clean break with long
discouraged (and actively deprecated) parts of the language.
</p>

<p>
The proposed change would resolve core issue
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4457.html#596">596</a> as no
longer relevant (NAD), and should simplify core issue
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4458.html#1351">1351</a>,
although that is marked as a Defect Report that was not yet applied to the working paper the
proposed wording below was drafted from.
</p>

<h2><a name="5.0">Compatibility Concerns</a></h2>
<p>
There is certainly some body of existing code that has not heeded the existing best practice
of discouraging dynamic exception specifications, and has not yet accounted for the feature
being deprecated in C++11.  It is not clear how much of such code would be expected to port
unmodified into a C++17 (or beyond) world, and the change is relatively simple - just strike
the (non-empty) dynamic exception specification to retain equivalent meaning.  The key difference
is that the <tt>unexpected</tt> handler will not now be called to translate unexpected exceptions.
In rare cases, this would allow a new exception type to propage, rather than calling <tt>terminate</tt>
to abort.  If enforcing that semantic is seen as important in production systems, there is a more
intrusive workaround available:
</p>
<p><pre><blockquote>
void legacy() <del>throw(something)</del>
<ins>try</ins>
{
    // function body as before
}
<ins>catch(const something&amp;) {</ins>
   <ins>throw;</ins>
<ins>}</ins>
<ins>catch(...) {</ins>
   <ins>terminate();</ins>
<ins>}</ins>

</blockquote></pre></p>

<p>
It is thought that the empty dynamic exception specification, <tt>throw()</tt>, was much more widely
used in practice, often in the mistaken impression that compilers would use this information to
optimize code generation where no exception could propagate, where in fact this is strictly a
pessimization that forces stack unwinding to the function exit, and then calling the <tt>unexcepted</tt>
callback in a manner that is guatanteed to fail before the subsequent call to <tt>terminate</tt>.
This paper proposes treating such (still deprecate) exception specifications as synonyms for
<tt>noexcept(true)</tt>, yielding the performance benefit many were originally expecting.
</p>
<p>
It should also be noted that at least one widely distributed compiler has still not implemented this
feature in 2015, and at least one vendor has expressed a desire to never implement the deprecated
feature (while that vendor <em>has</em> implemented the <tt>noexcept</tt> form of exception specification).
Code on that platform would not be adversely impacted by the proposed removal, and portable code
must always have allowed for the idiosynracies of this platform.
</p>
<p>
One remaining task is to survey popular open source libraries and see what level of usage, if any,
remains in large, easily accessible codebases.
</p>


<h2><a name="6.0">Proposed Wording</a></h2>


<h3><a name="STD_3.3.7">3.3.7 Class scope [basic.scope.class]</a></h3>
<p>
1 The following rules describe the scope of names declared in classes.
</p>
1) The potential scope of a name declared in a class consists not only of the declarative region
following the name’s point of declaration, but also of all function bodies, default arguments,
<del><i>exception-specification</i>s,</del> and <i>brace-or-equal-initializers</i> of non-static
data members in that class (including such things in nested classes).
</p>


<h3><a name="STD_3.4.1">3.4.1 Unqualified name lookup [basic.lookup.unqual]</a></h3>
<p>
7 A name used in the definition of a class <tt>X</tt> outside of a member function body,
default argument, <del><i>exception-specification</i>,</del> <i>brace-or-equal-initializer</i>
of a non-static data member, or nested class definition<sub>29</sub> shall be declared in one
of the following ways:
</p>

<p>
8 For the members of a class <tt>X</tt>, a name used in a member function body, in a default
argument, <del>in an <i>exception-specification</i>,</del> in the <i>brace-or-equal-initializer</i>
of a non-static data member (9.2), or in the definition of a class member outside of the definition
of <tt>X</tt>, following the member's <i>declarator-id</i><sub>31</sub>, shall be declared in one
of the following ways:
</p>

<p>
31) That is, an unqualified name that occurs, for instance, in a type in the
<i>parameter-declaration-clause</i> <del>or in the <i>exception-specification</i></del>.
</p>


<h3><a name="STD_8.4.2">8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]</a></h3>
<p>
4 [ <i>Example:</i>
</p>
<pre>
   struct S {
     constexpr S() = default;            // ill-formed: implicit S() is not constexpr
     S(int a = 0) = default;             // ill-formed: default argument
     void operator=(const S&amp;) = default; // ill-formed: non-matching return type
     ~S() <ins>noexcept(false)</ins><del>throw(int)</del> = default;          // deleted: exception specification does not match
   private:
     int i;
     S(S&amp;);                              // OK: private copy constructor
   };
   S::S(S&amp;) = default;                   // OK: defines copy constructor
</pre>
<p>
&mdash; <i>end example</i> ]
</p>


<h3><a name="STD_9.2">9.2 Class members [class.mem]</a></h3>
<p>
2 A class is considered a completely-defined object type (3.9) (or complete type) at the closing
<tt>}</tt> of the <i>class-specifier</i>. Within the class <i>member-specification</i>, the class
is regarded as complete within function bodies, default arguments, <i>using-declaration</i>s
introducing inheriting constructors (12.9), <del><i>exception-specification</i>s,</del> and
<i>brace-or-equal-initializer</i>s for non-static data members (including such things in nested
classes).  Otherwise it is regarded as incomplete within its own class <i>member-specification</i>.
</p>
<p>
3 [ <i>Note:</i> A single name can denote several function members provided their types are
sufficiently different (Clause13). &mdash; <i>end note</i> ]
</p>
<p>
4 A <i>brace-or-equal-initializer</i> shall appear only in the declaration of a data member.
(For static data members, see 9.4.2; for non-static data members, see 12.6.2). A
<i>brace-or-equal-initializer</i> for a non-static data member shall not directly or indirectly
cause the implicit definition of a defaulted default constructor for the enclosing class <del>or
the exception specification of that constructor</del>.
</p>

<h3><a name="STD_14.5">14.5 Template declarations [temp.decls]</a></h3>
<p>
2 For purposes of name lookup and instantiation, default arguments <del>and
<i>exception-specification</i>s</del> of function templates and default arguments <del>and
<i>exception-specification</i>s</del> of member functions of class templates are considered
definitions; each default argument <del>or <i>exception-specification</i></del> is a separate
definition which is unrelated to the function template definition or to any other default
arguments<del> or <i>exception-specification</i>s</del>.
</p>


<h3><a name="STD_14.5.3">14.5.3 Variadic templates [temp.variadic]</a></h3>
<p>
<del>
(4.7) &mdash; In a <i>dynamic-exception-specification</i> (15.4); the pattern is a <i>type-id</i>.
</del>
</p>


<h3><a name="STD_14.6">14.6 Name resolution [temp.res]</a></h3>
<p>
11 [<i>Note:</i> For purposes of name lookup, default arguments <del>and
<i>exception-specification</i>s</del> of function templates and default arguments <del>and
<i>exception-specification</i>s</del> of member functions of class templates are considered
definitions(14.5). &mdash; <i>end note</i> ]
</p>


<h3><a name="STD_14.6.4.1">14.6.4.1 Point of instantiation [temp.point]</a></h3>
<p>
<del>
3 For an <i>exception-specification</i> of a function template specialization or specialization of
a member function of a class template, if the <i>exception-specification</i> is implicitly
instantiated because it is needed by another template specialization and the context that requires
it depends on a template parameter, the point of instantiation of the <i>exception-specification</i>
is the point of instantiation of the specialization that requires it. Otherwise, the point of
instantiation for such an <i>exception-specification</i> immediately follows the namespace scope
declaration or definition that requires the <i>exception-specification</i>.
</del>
</p>


<h3><a name="STD_14.7.1">14.7.1 Implicit instantiation [temp.inst]</a></h3>
<p>
1 Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly
specialized (14.7.3), the class template specialization is implicitly instantiated when the
specialization is referenced in a context that requires a completely-defined object type or when
the completeness of the class type affects the semantics of the program. [ <i>Note:</i> Within a
template declaration, a local class or enumeration and the members of a local class are never
considered to be entities that can be separately instantiated (this includes their default arguments,
<del><i/>exception-specification</i>s,</del> and non-static data member initializers, if any). As a
result, the dependent names are looked up, the semantic constraints are checked, and any templates
used are instantiated as part of the instantiation of the entity within which the local class or
enumeration is declared. &mdash; <i>end note</i> ]  The implicit instantiation of a class template
specialization causes the implicit instantiation of the declarations, but not of the definitions<del>,
</del><ins>or</ins> default arguments<del>, or <i>exception-specifications</i></del> of the class
member functions, member classes, scoped member enumerations, static data members and member
templates; and it causes the implicit instantiation of the definitions of unscoped member
enumerations and member anonymous unions. However, for the purpose of determining whether an
instantiated redeclaration of a member is valid according to 9.2, a declaration that corresponds to
a definition in the template is considered to be a definition.  [ <i>Example:</i>
</p>

<p>
<del>
15 The <i>exception-specification</i> of a function template specialization is not instantiated
along with the function declaration; it is instantiated when needed (15.4). If such an
<i>exception-specification</i> is needed but has not yet been instantiated, the dependent names are
looked up, the semantics constraints are checked, and the instantiation of any template used in the
<i>exception-specification</i> is done as if it were being done as part of instantiating the
declaration of the specialization at that point.
</del>
</p>


<h3><a name="STD_14.7.2">14.7.2 Explicit instantiation [temp.explicit]</a></h3>
<p>
12 The usual access checking rules do not apply to names used to specify explicit instantiations.
[ <i>Note:</i> In particular, the template arguments and names used in the function declarator
(including parameter types<del>,</del> <ins>and</ins> return types <del>and exception
specifications</del>) may be private types or objects which would normally not be accessible and
the template may be a member template or member function which would not normally be accessible.
&mdash; <i>end note</i> ]
</p>


<h3><a name="STD_14.8.2">14.8.2 Template argument deduction [temp.deduct]</a></h3>
<p>
7 The substitution occurs in all types and expressions that are used in the function type and in
template parameter declarations. The expressions include not only constant expressions such as those
that appear in array bounds or as nontype template arguments but also general expressions (i.e.,
non-constant expressions) inside <tt>sizeof</tt>, <tt>decltype</tt>, and other contexts that allow
non-constant expressions. The substitution proceeds in lexical order and stops when a condition that
causes deduction to fail is encountered. <del>[ <i>Note:</i> The equivalent substitution in
exception specifications is done only when the <i>exception-specification</i> is instantiated, at
which point a program is ill-formed if the substitution results in an invalid type or expression.
&mdash; <i>end note</i> ]
</p>


<h3><a name="STD_15.4">15.4 Exception specifications [except.spec]</a></h3>
<p>
1 The <i>exception specification</i> of a function is a (possibly empty) set
of types, indicating that the function might exit via an exception <del>that matches a
handler of one of the types in the set</del>; the (conceptual) set of all types is used
to denote that the function might exit via an exception of arbitrary type. If the
set is empty, the function is said to have a <i>non-throwing exception specification</i>.
The exception specification is either defined explicitly by using an
<i>exception-specification</i> as a suffix of a function declaration's declarator (8.3.5)
or implicitly.
</p>
<p>
<pre>
   <i>exception-specification:</i>
      <del><i>dynamic-exception-specification</i></del>
      <del><i>noexcept-specification</i></del>
      <ins>noexcept ( <i>constant-expression</i> )</ins>
      <ins>noexcept</ins>
      <ins>throw ( )</ins>

   <del><i>dynamic-exception-specification:</i></del>
      <del>throw ( <i>type-id-list<sub>opt</sub></i> )</del>

   <del><i>type-id-list:</i></del>
      <del><i>type-id ...<sub>opt</sub></i></del>
      <del><i>type-id-list , type-id ...<sub>opt</sub></i></del>

   <del>noexcept-specification:</del>
      <del>noexcept ( <i>constant-expression</i> )</del>
      <del>noexcept</del>
</pre>
</p>
<p>
In a<ins>n</ins> <i><ins>exception</ins><del>noexcept</del>-specification</i>, the
<i>constant-expression</i>, if supplied, shall be a constant expression (5.20) that is
contextually converted to <tt>bool</tt> (Clause 4).  A <tt>(</tt> token that follows
<tt>noexcept</tt> is part of the <i><ins>exception</ins><del>noexcept</del>-specification</i>
and does not commence an initializer (8.5).  <ins>The <i>exception-specification</i>
<tt>throw()</tt> is deprecated (see Annex D), and equivalent to the <i>exception-specification</i>
<tt>noexcept</tt>.</ins>
</p>

<p>2 An <i>exception-specification</i> shall appear only on a function declarator for a
function type, pointer to function type, reference to function type, or pointer to member
function type that is the top-level type of a declaration or definition, or on such a type
appearing as a parameter or return type in a function declarator. An <i>exception-specification</i>
shall not appear in a typedef declaration or <i>alias-declaration</i>.  <i>[Example:</i>
<pre>
  void f() <ins>noexcept</ins><del>throw(int)</del>;             <i>// OK</i>
  void (*fp)() <ins>noexcept</ins><del>throw (int)</del>;        <i>// OK</i>
  void g(void pfa() <ins>noexcept</ins><del>throw(int)</del>);   <i>// OK</i>
  typedef int (*pf)() <ins>noexcept</ins><del>throw(int)</del>;  <i>// ill-formed</i>
</pre>
&mdash; <i>end example</i> ]
</p>
<p>
<del>
A type denoted in a <i>dynamic-exception-specification</i> shall not denote an incomplete
type or an rvalue reference type. A type denoted in a <i>dynamic-exception-specification</i>
shall not denote a pointer or reference to an incomplete type, other than &quot;pointer to <i>cv</i>
<tt>void</tt>&quot;. A type <i>cv</i> <tt>T</tt>, &quot;array of <tt>T</tt>&quot;, or
&quot;function returning <tt>T</tt>&quot; denoted in a <i>dynamic-exception-specification</i>
is adjusted to type <tt>T</tt>, &quot;pointer to <tt>T</tt>&quot;, or &quot;pointer to function
returning <tt>T</tt>&quot;, respectively.  A <i>dynamic-exception-specification</i> denotes an
exception specification that is the set of adjusted types specified thereby.
</del>
</p>

<p>
3 The <i>exception-specification</i> <tt>noexcept</tt> or <tt>noexcept(<i>constant-expression</i>)</tt>,
where the <i>constant-expression</i> yields <tt>true</tt>, denotes an exception specification that
is the empty set. The <i>exception-specification</i> <tt>noexcept(<i>constant-expression</i>)</tt>,
where the <i>constant-expression</i> yields <tt>false</tt>, or the absence of an
<i>exception-specification</i> in a function declarator other than that for a destructor (12.4)
or a deallocation function (3.7.4.2) denotes an exception specification that is the set of all types.
</p>

<p>
4 Two <i>exception-specification</i>s are <i>compatible</i> if the sets of types they denote are
the same.
</p>

<p>
5 If any declaration of a function has an <i>exception-specification</i> <del>that is not a
<i>noexcept-specification</i></del> allowing <ins>no</ins><del>all</del> exceptions, all declarations,
including the definition and any explicit specialization, of that function shall have a compatible
<i>exception-specification</i>.  If any declaration of a pointer to function, reference to
function, or pointer to member function has an <i>exception-specification</i>, all occurrences of that
declaration shall have a compatible <i>exception-specification</i>.  If a declaration of a function
has an implicit exception specification, other declarations of the function shall not specify an
<i>exception-specification</i>.  In an explicit instantiation an <i>exception-specification</i> may
be specified, but is not required. If an <i>exception-specification</i> is specified in an explicit
instantiation directive, it shall be compatible with the <i>exception-specifications</i> of other
declarations of that function. A diagnostic is required only if the <i>exception-specification</i>s
are not compatible within a single translation unit.
</p>

<p>
6 If a virtual function has an exception specification, all declarations, including the definition,
of any function that overrides that virtual function in any derived class shall only allow exceptions
that are allowed by the exception specification of the base class virtual function, unless the
overriding function is defined as deleted. [ <i>Example:</i>
<pre>
     struct B {
       virtual void f() <ins>noexcept</ins><del>throw (int, double)</del>;
       virtual void g();
     };

     struct D: B {
       void f();               <i>// ill-formed</i>
       void g() <ins>noexept</ins><del>throw (int)</del>;      <i>// OK</i>
     };
</pre>
The declaration of <tt>D::f</tt> is ill-formed because it allows all exceptions, whereas <tt>B::f</tt>
allows <ins>no exceptions</ins><del>only <tt>int</tt> and <tt>double</tt></del>. &mdash; <i>end
example</i>]  A similar restriction applies to assignment to and initialization of pointers to
functions, pointers to member functions, and references to functions: the target entity shall allow
at least the exceptions allowed by the source value in the assignment or initialization.
[ <i>Example:</i>
<pre>
     class A { /∗...∗/ };
     void (*pf1)();      <i>// no exception specification</i>
     void (*pf2)() <ins>noexcept</ins><del>throw(A)</del>;

     void f() {
       pf1 = pf2;        <i>// OK: <tt>pf1</tt> is less restrictive</i>
       pf2 = pf1;        <i>// error: <tt>pf2</tt> is more restrictive</i>
     }
</pre>
&mdash; <i>end example</i> ]
</p>

<p>
7 In such an assignment or initialization, <i>exception-specification</i>s on return types and
parameter types shall be compatible. In other assignments or initializations,
<i>exception-specification</i>s shall be compatible.
</p>

<p>
<del>
8 An <i>exception-specification</i> can include the same type more than once and can include
classes that are related by inheritance, even though doing so is redundant. [ <i>Note:</i> An
<i>exception-specification</i> can also include the class <tt>std::bad_exception</tt> (18.8.2).
— <i>end note</i> ]
</del>
</p>

<p>
9 <del>A function is said to allow an exception of type <tt>E</tt> if its exception specification
contains a type <tt>T</tt> for which a handler of type <tt>T</tt> would be a match (15.3) for an
exception of type <tt>E</tt>.</del>  A function is said to allow all exceptions if its exception
specification is the set of all types.  <ins>Otherwise a function does not allow any exceptions.</ins>
</p>

<p>
10 Whenever an exception <del>of type <tt>E</tt></del> is thrown and the search for a handler (15.3)
encounters the outermost block of a function with an exception specification that does not allow
<ins>any exceptions</ins><del><tt>E</tt>, then</del>,<ins> the function
<tt>std::terminate()</tt> is called (15.5.1).</ins>
</p>
<p>
<del>
(10.1) &mdash; if the function definition has a <i>dynamic-exception-specification</i>, the function
<tt>std::unexpected()</tt> is called (15.5.2),
</del>
</p>
<p>
<del>
(10.2) &mdash; otherwise, the function <tt>std::terminate()</tt> is called (15.5.1).
</del>
<p>
<del>[ <i>Example:</i></del>
</p>
<pre>
     <del>class X { };</del>
     <del>class Y { };</del>
     <del>class Z: public X { };</del>
     <del>class W { };</del>

     <del>void f() throw (X, Y) {</del>
       <del>int n = 0;</del>
       <del>if (n) throw X();  <i>// OK</i></del>
       <del>if (n) throw Z();  <i>// also OK</i></del>
       <del>throw W();         <i>// will call</i> <tt>std::unexpected()</tt></del>
     <del>}</del>
</pre>
<p>
<del>&mdash; <i>end example</i> ]
</p>
<p>
<del>
[<i>Note:</i> A function can have multiple declarations with different non-throwing
<i>exception-specifications</i>; for this purpose, the one on the function definition is used.
&mdash; <i>end note</i> ]
</del>
</p>

<p>
11 An implementation shall not reject an expression merely because when executed it throws or might
throw an exception that the containing function does not allow. [ <i>Example:</i>
<pre>
     extern void f() throw(<del>X, Y</del>);
     void g() <del>throw(X)</del> {
       f();     <i>// OK</i>
     }
</pre>
the call to <tt>f</tt> is well-formed even though when called, <tt>f</tt> might throw <ins>an</ins>
exception <del><tt>Y</tt></del> that <tt>g</tt> does not allow. &mdash; <i>end example</i> ]
</p>

<p>
12 [ <i>Note:</i> An exception specification is not considered part of a function’s type; see 8.3.5.
&mdash; <i>end note</i> ]
</p>

<p>
13 A potential exception of a given context is either a type that might be thrown as an exception
or a pseudo-type, denoted by &quot;any&quot;, that represents the situation where an exception of
an arbitrary type might be thrown.  A subexpression <tt>e1</tt> of an expression <tt>e</tt> is an
immediate subexpression if there is no subexpression <tt>e2</tt> of <tt>e</tt> such that <tt>e1</tt>
is a subexpression of <tt>e2</tt>.
</p>

<p>
14 The set of potential exceptions of a function, function pointer, or member function pointer
<tt>f</tt> is <ins>the set denoted by the exception specification of <tt>f</tt>.</ins><del>defined as
follows:</del>
</p>
<p>
<del>
(14.1) &mdash; If the exception specification of <tt>f</tt> is the set of all types, the set consists
of the pseudo-type &quot;any&quot;.
</del>
</p>
<p>
<del>
(14.2) &mdash; Otherwise, the set consists of every type in the exception specification of <tt>f</tt>.
</del>
</p>
<p>

<p>
15 The set of potential exceptions of an expression <tt>e</tt> is empty if <tt>e</tt> is a core
constant expression (5.20). Otherwise, it is the union of the sets of potential exceptions of the
immediate subexpressions of <tt>e</tt>, including default argument expressions used in a function
call, combined with a set <tt>S</tt> defined by the form of <tt>e</tt>, as follows:
</p>
<p>
(15.1) &mdash; If <tt>e</tt> is a function call (5.2.2):
</p>
<p>
(15.1.1) &mdash; If its <i>postfix-expression</i> is a (possibly parenthesized) <i>id-expression</i>
(5.1.1), class member access (5.2.5), or pointer-to-member operation (5.5) whose <i>cast-expression</i>
is an <i>id-expression</i>, <tt>S</tt> is the set of potential exceptions of the entity selected by
the contained <i>id-expression</i> (after overload resolution, if applicable).
</p>
<p>
(15.1.2) &mdash; Otherwise, <tt>S</tt> <ins>is the set of all types</ins><del>contains the pseudo-type
&quot;any&quot;</del>.
</p>
<p>
(15.2) &mdash; If <tt>e</tt> implicitly invokes a function (such as an overloaded operator, an
allocation function in a <i>new-expression</i>, or a destructor if <tt>e</tt> is a full-expression
(1.9)), <tt>S</tt> is the set of potential exceptions of the function.
</p>
<p>
(15.3) &mdash; if <tt>e</tt> is a throw-expression (5.17), <tt>S</tt> <ins>is the set of all
types</ins><del>consists of the type of the exception object that would be initialized by the operand,
if present, or the pseudo-type &quot;any&quot; otherwise</del>.
</p>
<p>
(15.4) &mdash; if <tt>e</tt> is a <tt>dynamic_cast</tt> expression that casts to a reference type and
requires a run-time check (5.2.7), <tt>S</tt> <ins>is the set of all types</ins><del>consists of the
type <tt>std::bad_cast</tt></del>.
</p>
<p>
(15.5) &mdash; if <tt>e</tt> is a typeid expression applied to a glvalue expression whose type is a
polymorphic class type (5.2.8), <tt>S</tt> <ins>is the set of all types</ins><del>consists of the type
<tt>std::bad_typeid</tt></del>.
</p>
<p>
(15.6) &mdash; if <tt>e</tt> is a new-expression with a non-constant expression in the
<i>noptr-new-declarator</i> (5.3.4), <tt>S</tt> <ins>is the set of all types</ins><del>consists of the
type <tt>std::bad_array_new_length</tt></del>.
</p>
<p>
[ <i>Example:</i> Given the following declarations
<pre>
    void f() <del>throw(int)</del><ins>noexcept(false)</ins>;
    void g();
    struct A { A(); };
    struct B { B() noexcept; };
    struct D { D() <del>throw (double)</del><ins>noexcept(false)</ins>; };
</pre>
the set of potential exceptions for some sample expressions is:
</p>
<p>
(15.<del>7</del><ins>6.1</ins>) &mdash; for <tt>f()</tt>, the set <ins>is the set of all types</ins>
<del>consists of <tt>int</tt></del>;
</p>
<p>
(15.<del>8</del><ins>6.2</ins>) &mdash; for <tt>g()</tt>, the set <ins>is the set of all types</ins>
<del>consists of &quot;any&quot;</del>;
</p>
<p>
(15.<del>9</del><ins>6.3</ins>) &mdash; for <tt>new A</tt>, the set <ins>is the set of all types</ins>
<del>consists of &quot;any&quot;</del>;
</p>
<p>
(15.<del>10</del><ins>6.4</ins>) &mdash; for <tt>B()</tt>, the set is empty;
</p>
<p>
(15.<del>11</del><ins>6.5</ins>) &mdash; for <tt>new D</tt>, the set <ins>is the set of all types</ins>
<del>consists of &quot;any&quot; and <tt>double</tt></del>.
</p>
<p>
&mdash; <i>end example</i> ]
</p>

<p>
16 Given a member function <tt>f</tt> of some class <tt>X</tt>, where <tt>f</tt> is an inheriting
constructor (12.9) or an implicitly-declared special member function, the <i>set of potential
exceptions of the implicitly-declared member function</i> <tt>f</tt> consists of all the members
from the following sets:
</p>
<p>
(16.1) &mdash; if <tt>f</tt> is a constructor,
</p>
<p>
(16.1.1) &mdash; the sets of potential exceptions of the constructor invocations
</p>
<p>
(16.1.1.1) &mdash; for <tt>X</tt>'s non-variant non-static data members,
</p>
<p>
(16.1.1.2) &mdash; for <tt>X</tt>'s direct base classes, and
</p>
<p>
(16.1.1.3) &mdash; if <tt>X</tt> is non-abstract (10.4), for <tt>X</tt>'s virtual base classes,
</p>
<p>
(including default argument expressions used in such invocations) as selected by overload
resolution for the implicit definition of <tt>f</tt> (12.1). [ <i>Note:</i> Even though destructors
for fully-constructed subobjects are invoked when an exception is thrown during the execution of a
constructor (15.2), their exception specifications do not contribute to the exception specification
of the constructor, because an exception thrown from such a destructor could never escape the
constructor (15.1, 15.5.1). &mdash; <i>end note</i>]
<p>
(16.1.2) &mdash; the sets of potential exceptions of the initialization of non-static data members
from <i>brace-or-equal-initializer</i>s that are not ignored (12.6.2);
</p>
<p>
(16.2) &mdash; if <tt>f</tt> is an assignment operator, the sets of potential exceptions of the
assignment operator invocations for <tt>X</tt>'s non-variant non-static data members and for
<tt>X</tt>'s direct base classes (including default argument expressions used in such invocations),
as selected by overload resolution for the implicit definition of <tt>f</tt> (12.8);
</p>
<p>
(16.3) &mdash; if <tt>f</tt> is a destructor, the sets of potential exceptions of the destructor
invocations for <tt>X</tt>'s non-variant non-static data members and for <tt>X</tt>'s virtual and
direct base classes.
</p>

<p>
17 An inheriting constructor (12.9) and an implicitly-declared special member function (Clause 12)
are considered to have an implicit exception specification, as follows, where <tt>S</tt> is the set
of potential exceptions of the implicitly-declared member function:
</p>
<p>
(17.1) &mdash; if <tt>S</tt> <ins>is the set of all types</ins><del>contains the pseudo-type
&quot;any&quot;</del>, the implicit exception specification is the set of all types;
</p>
<p>
(17.2) &mdash; otherwise, the implicit exception specification contains all the types in <tt>S</tt>.
</p>
<p>
[ <i>Note:</i> An instantiation of an inheriting constructor template has an implied exception
specification as if it were a non-template inheriting constructor. &mdash; <i>end note</i> ]
[ <i>Example:</i>
</p><pre>
   struct A {
     A(int = (A(5), 0)) noexcept;
     A(const A&amp;) throw();
     A(A&amp;&amp;) throw();
     ~A() <del>throw(X)</del>;
   };
   struct B {
     B() throw();
     B(const B&amp;) = default;  <i>// exception specification contains no types</i>
     B(B&amp;&amp;, int = (throw Y(), 0)) noexcept;
     ~B() <ins>noexcept(false)</ins><del>throw(Y)</del>;
   };
   int n = 7;
   struct D : public A, public B {
     int * p = new (std::nothrow) int[n];
     <i>// exception specification of D::D() contains <ins>the set of all types</ins><del>X and std::bad_array_new_length</del></i>
     <i>// exception specification of D::D(const D&amp;) contains no types</i>
     <i>// exception specification of D::D(D&amp;&amp;) contains <ins>the set of all types</ins><del>Y</del></i>
     <i>// exception specification of D::~D() contains <ins>the set of all types</ins><del>X and Y</del></i>
   };
</pre><p>
Furthermore, if <tt>A::~A()</tt> <del>or <tt>B::~B()</tt></del> were virtual, <tt>D::~D()</tt> would
not be as restrictive as that of <tt>A::~A</tt>, and the program would be ill-formed since a function
that overrides a virtual function from a base class shall have an <i>exception-specification</i> at
least as restrictive as that in the base class. &mdash; <i>end example</i> ]
</p>

<p>
18 A deallocation function (3.7.4.2) with no explicit <i>exception-specification</i> has an exception
specification that is the empty set.
</p>

<p>
19 An <i>exception-specification</i> is considered to be <i>needed</i> when:
</p>
<p>
(19.1) &mdash; in an expression, the function is the unique lookup result or the selected member of
a set of overloaded functions (3.4, 13.3, 13.4);
</p>
<p>
(19.2) &mdash; the function is odr-used (3.2) or, if it appears in an unevaluated operand, would be
odr-used if the expression were potentially-evaluated;
</p>
<p>
(19.3) &mdash; the <i>exception-specification</i> is compared to that of another declaration (e.g.,
an explicit specialization or an overriding virtual function);
</p>
<p>
(19.4) &mdash; the function is defined; or
</p>
<p>
(19.5) &mdash; the <i>exception-specification</i> is needed for a defaulted special member function
that calls the function. [ <i>Note:</i> A defaulted declaration does not require the
<i>exception-specification</i> of a base member function to be evaluated until the implicit
<i>exception-specification</i> of the derived function is needed, but an explicit
<i>exception-specification</i> needs the implicit <i>exception-specification</i> to compare against.
&mdash; <i>end note</i> ]
</p>
<p>
</p>
The <i>exception-specification</i> of a defaulted special member function is evaluated as described
above only when needed; similarly, the <i>exception-specification</i> of a specialization of a
function template or member function of a class template is instantiated only when needed.
</p>

<p>
<del>
20 In a <i>dynamic-exception-specification</i>, a <i>type-id</i> followed by an ellipsis is a
pack expansion (14.5.3).
</del>
</p>

<p>
<del>
21 [ <i>Note:</i> The use of <i>dynamic-exception-specification</i>s is deprecated (see Annex D).
&mdash; <i>end note</i> ]
</del>
</p>


<h3><a name="STD_15.5">15.5 Special functions [except.special]</a></h3>
<p>
1 The function<del>s</del> <tt>std::terminate()</tt> (15.5.1) <del>and <tt>std::unexpected()</tt>
(15.5.2) are</del><ins>is</ins> used by the exception handling mechanism for coping with errors
related to the exception handling mechanism itself. The function <tt>std::current_exception()</tt>
(18.8.5) and the class <tt>std::nested_exception</tt> (18.8.6) can be used by a program to capture
the currently handled exception.
</p>

<h3><a name="STD_15.5.1">15.5.1 The std::terminate() function [except.terminate]</a></h3>
<p>
1 In some situations exception handling must be abandoned for less subtle error handling techniques.
[ <i>Note:</i> These situations are:
</p>
<p>
(1.1) &mdash; when the exception handling mechanism, after completing the initialization of the
exception object but before activation of a handler for the exception (15.1), calls a function that
exits via an exception, or
</p>
<p>
(1.2) &mdash; when the exception handling mechanism cannot find a handler for a thrown exception
(15.3), or
</p>
<p>
(1.3) &mdash; when the search for a handler (15.3) encounters the outermost block of a function with
a<ins>n</ins> <i><ins>exception</ins><del>noexcept</del>-specification</i> that does not allow the
exception (15.4), or
</p>
<p>
(1.4) &mdash; when the destruction of an object during stack unwinding (15.2) terminates by throwing
an exception, or
</p>
<p>
(1.5) &mdash; when initialization of a non-local variable with static or thread storage duration
(3.6.2) exits via an exception, or
</p>
<p>
(1.6) &mdash; when destruction of an object with static or thread storage duration exits via an
exception (3.6.3), or
</p>
<p>
(1.7) &mdash; when execution of a function registered with <tt>std::atexit</tt> or
<tt>std::at_quick_exit</tt> exits via an exception (18.5), or
</p>
<p>
(1.8) &mdash; when a <i>throw-expression</i> (5.17) with no operand attempts to rethrow an exception
and no exception is being handled (15.1), or
</p>
<p>
<del>
(1.9) &mdash; when <tt>std::unexpected</tt> exits via an exception of a type that is not allowed by
the previously violated exception specification, and <tt>std::bad_exception</tt> is not included in
that exception specification (15.5.2), or
</del>
</p>
<p>
<del>
(1.10) &mdash; when the implementation’s default unexpected exception handler is called (D.8.1), or
</del>
</p>
<p>
(1.11) &mdash; when the function <tt>std::nested_exception::rethrow_nested</tt> is called for an
object that has captured no exception (18.8.6), or
</p>
<p>
(1.12) &mdash; when execution of the initial function of a thread exits via an exception (30.3.1.2), or
</p>
<p>
(1.13) &mdash; when the destructor or the copy assignment operator is invoked on an object of type
<tt>std::thread</tt> that refers to a joinable thread (30.3.1.3, 30.3.1.4), or
</p>
<p>
(1.14) &mdash; when a call to a <tt>wait()</tt>, <tt>wait_until()</tt>, or <tt>wait_for()</tt>
function on a condition variable (30.5.1, 30.5.2) fails to meet a postcondition.
</p>
<p>
&mdash; <i>end note</i> ]
</p>

<p>
2 In such cases, <tt>std::terminate()</tt> is called (18.8.3). In the situation where no matching
handler is found, it is implementation-defined whether or not the stack is unwound before
<tt>std::terminate()</tt> is called. In the situation where the search for a handler (15.3) encounters
the outermost block of a function with a<ins>n</ins>
<i><ins>exception</ins><del>noexcept</del>-specification</i> that does not allow the exception (15.4),
it is implementation-defined whether the stack is unwound, unwound partially, or not unwound at all
before <tt>std::terminate()</tt> is called.  In all other situations, the stack shall not be unwound
before <tt>std::terminate()</tt> is called.  An implementation is not permitted to finish stack
unwinding prematurely based on a determination that the unwind process will eventually cause a call
to <tt>std::terminate()</tt>.
</p>


<h3><a name="STD_15.5.2"><del>15.5.2 The <tt>std::unexpected()</tt> function [except.unexpected]</del></a></h3>
<p>
<del>
1 If a function with a <i>dynamic-exception-specification</i> exits via an exception of a type that
is not allowed by its exception specification, the function <tt>std::unexpected()</tt> is called
(D.8) immediately after completing the stack unwinding for the former function.
</del>
</p>
<p>
<del>
2 [ <i>Note:</i> By default, <tt>std::unexpected()</tt> calls <tt>std::terminate()</tt>, but a
program can install its own handler function (D.8.2).  In either case, the constraints in the
following paragraph apply. &mdash; <i>end note</i> ]
</del>
</p>
<p>
<del>
3 The <tt>std::unexpected()</tt> function shall not return, but it can throw (or rethrow) an
exception.  If it throws a new exception which is allowed by the exception specification which
previously was violated, then the search for another handler will continue at the call of the
function whose exception specification was violated. If it exits via an exception of a type that the
<i>dynamic-exception-specification</i> does not allow, then the following happens: If the
<i>dynamic-exception-specification</i> does not include the class <tt>std::bad_exception</tt> (18.8.2)
then the function <tt>std::terminate()</tt> is called, otherwise the thrown exception is replaced by
an implementation-defined object of type <tt>std::bad_exception</tt> and the search for another
handler will continue at the call of the function whose <i>dynamic-exception-specification</i> was
violated.
</del>
</p>
<p>
<del>
4 [<i>Note:</i> Thus, a <i>dynamic-exception-specification</i> guarantees that a function exits only
via an exception of one of the listed types. If the <i>dynamic-exception-specification</i> includes
the type <tt>std::bad_exception</tt> then any exception type not on the list may be replaced by
<tt>std::bad_exception</tt> within the function <tt>std::unexpected()</tt>. &mdash; <i>end note</i>]
</del>
</p>


<h3><a name="STD_17.6.5.12">17.6.5.12 Restrictions on exception handling [res.on.exception.handling]</a></h3>
<p>
1 Any of the functions defined in the C++ standard library can report a failure by throwing an
exception of a type described in its <b>Throws:</b> paragraph.  An implementation may strengthen
the exception specification for a non-virtual function by adding a non-throwing
<i><ins>exception</ins><del>noexcept</del>-specification</i>.
</p>
<p>
2 A function may throw an object of a type not listed in its <b>Throws</b> clause if its type is
derived from a type named in the <b>Throws</b> clause and would be caught by an exception handler
for the base type.
</p>
<p>
3 Functions from the C standard library shall not throw exceptions<sub>191</sub> except when such a
function calls a program-supplied function that throws an exception.<sub>192</sub>
</p>
<p>
4 Destructor operations defined in the C++ standard library shall not throw exceptions. Every
destructor in the C++ standard library shall behave as if it had a non-throwing exception
specification. Any other functions efined in the C++ standard library that do not have an
<i>exception-specification</i> may throw implementation-defined exceptions unless otherwise
specified.<sub>193</sub> An implementation may strengthen this implicit <i>exception-specification</i>
by adding an explicit one.<sub><del>194</del></sub>
</p>
<p>
<del>
194) That is, an implementation may provide an explicit <i>exception-specification</i> that defines
the subset of &quot;any&quot; exceptions thrown by that function. This implies that the implementation
may list implementation-defined types in such an <i>exception-specification</i>.
</del>
</p>

<h3><a name="STD_18.8">18.8 Exception Handling [support.exception]</a></h3>
<p>
1 The header <tt>&lt;exception&gt;</tt> defines several types and functions related to the handling
of exceptions in a C++ program.
</p>

<h4><a name="STD_18.8_synopsis">Header &lt;exception&gt; synopsis</a></h4>
<pre>
     namespace std {
       class exception;
       class bad_exception;
       class nested_exception;

       <del>typedef void (*unexpected_handler)();</del>
       <del>unexpected_handler get_unexpected() noexcept;</del>
       <del>unexpected_handler set_unexpected(unexpected_handler f) noexcept;</del>
       <del>[[noreturn]] void unexpected();</del>

       typedef void (*terminate_handler)();
       terminate_handler get_terminate() noexcept;
       terminate_handler set_terminate(terminate_handler f) noexcept;
       [[noreturn]] void terminate() noexcept;

       int uncaught_exceptions() noexcept;
       <i>// D.<del>9</del><ins>X</ins>, uncaught_exception (deprecated)</i>
       bool uncaught_exception() noexcept;

       typedef unspecified exception_ptr;

       exception_ptr current_exception() noexcept;
       [[noreturn]] void rethrow_exception(exception_ptr p);
       template &lt;class E&gt; exception_ptr make_exception_ptr(E e) noexcept;
       template &lt;class T&gt; [[noreturn]] void throw_with_nested(T&amp;&amp; t);
       template &lt;class E&gt; void rethrow_if_nested(const E&amp; e);
     }
</pre>


<h3><a name="STD_18.8.2">18.8.2 Class <tt>bad_exception</tt> [bad.exception]</a></h3>
<p>
1 The class <tt>bad_exception</tt> defines the type of object<del>s</del> <ins>referenced by the
<tt>exception_ptr</tt> returned from a call to <tt>current_exception</tt> (18.8.5 [propagation])
when the currently active exception object fails to copy</ins><del>thrown as described in
(15.5.2)</del>.
</p>


<h3><a name="STD_23.3.2.8">23.3.2.8 Zero sized arrays [array.zero]</a></h3>
<p>
4 Member function <tt>swap()</tt> shall have a<ins>n</ins>
<i><ins>exception</ins><del>noexcept</del>-specification</i> which is equivalent to
<tt>noexcept(true)</tt>.
</p>


<h3><a name="STD_B">Annex B (informative) Implementation quantities [implimits]</a></h3>
<p>
<del>
(2.40) &mdash; Throw specifications on a single function declaration [256].
</del>
</p>


<h3><a name="STD_D.4">D.4 Dynamic exception specifications [depr.except.spec]</a></h3>
<p>
1 The <ins><i>exception-specification</i> <tt>throw()</tt></ins><del>use of
<i>dynamic-exception-specification</i>s</del> is deprecated.
</p>


<h3><a name="STD_D.8"><del>D.8 Violating <i>exception-specifications</i> [exception.unexpected]</del></a></h3>

<h3><a name="STD_D.8.1"><del>D.8.1 Type <tt>unexpected_handler</tt> [unexpected.handler]</del></a></h3>
<p>
<del>
<tt>typedef void (*unexpected_handler)();</tt>
</del>
</p>
<p>
<del>
1 The type of a <i>handler function</i> to be called by <tt>unexpected()</tt> when a function attempts
to throw an exception not listed in its <i>dynamic-exception-specification</i>.
</del>
</p>
<p>
<del>
2 <i>Required behavior:</i> An <tt>unexpected_handler</tt> shall not return. See also 15.5.2.
</del>
</p>
<p>
<del>
3 <i>Default behavior:</i> The implementation's default <tt>unexpected_handler</tt> calls
<tt>std::terminate()</tt>.
</del>
</p>

<h3><a name="STD_D.8.2"><del>D.8.2 <tt>set_unexpected</tt> [set.unexpected]</del></a></h3>
<p>
<del>
<tt>unexpected_handler set_unexpected(unexpected_handler f) noexcept;</tt>
</del>
</p>
<p>
<del>
1 <i>Effects:</i> Establishes the function designated by <tt>f</tt> as the current
<tt>unexpected_handler</tt>.
</del>
</p>
<p>
<del>
2 <i>Remark:</i> It is unspecified whether a null pointer value designates the default
<tt>unexpected_handler</tt>.
</del>
</p>
<p>
<del>
3 <i>Returns:</i> The previous <tt>unexpected_handler</tt>.
</del>
</p>

<h3><a name="STD_D.8.3"><del>D.8.3 <tt>get_unexpected</tt> [get.unexpected]</del></a></h3>
<p>
<del>
<tt>unexpected_handler get_unexpected() noexcept;</tt>
</del>
</p>
<p>
<del>
1 <i>Returns:</i> The current <tt>unexpected_handler</tt>. [ <i>Note:</i> This may be a null pointer
value. &mdash; <i>end note</i> ]
</del>
</p>

<h3><a name="STD_D.8.4"><del>D.8.4 <tt>unexpected</tt> [unexpected]</del></a></h3>
<p>
<del>
<tt>[[noreturn]] void unexpected();</tt>
</del>
</p>
<p>
<del>
1 <i>Remarks:</i> Called by the implementation when a function exits via an exception not allowed by
its <i>exception-specification</i> (15.5.2), in effect after evaluating the <i>throw-expression</i>
(D.8.1). May also be called directly by the program.
</del>
</p>
<p>
<del>
2 <i>Effects:</i> Calls the current <tt>unexpected_handler</tt> function. [ <i>Note:</i> A default
<tt>unexpected_handler</tt> is always considered a callable handler in this context. &mdash;
<i>end note</i> ]
</del>
</p>


<h2><a name="7.0">Acknowledgements</a></h2>
<p>
</p>


<h2><a name="8.0">VIII. References</a></h2>
<ul>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0741.htm">N0741</a> Exceptions specifications in the Standard Library, Mats Henricson</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html">N3051</a> Deprecating Exception Specifications, Doug Gregor</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4533">N4533</a> Make exception specifications be part of the type system, version 3, Jens Maurer</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4086">N4086</a> Removing trigraphs??!, Richard Smith</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4168">N4168</a> Removing <tt>auto_ptr</tt>, Billy Baker</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190">N4190</a> Removing <tt>auto_ptr</tt>, <tt>random_shuffle()</tt>, And Old <tt>&lt;functional&gt;</tt> Stuff, Stephan T. Lavavej</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0001r0.html">P0001R0</a> Remove Deprecated Use of the <tt>register</tt> Keyword</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0002r0.html">P0002R0</a> Remove Deprecated <tt>operator++(bool)</tt></li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0004r0.html">P0004R0</a> Remove Deprecated iostreams aliases</tt></li>
</ul>

</body>
</html>
