<!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=UTF8">

<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; }

blockquote.note {
  background-color: #E0E0E0;
  padding-left: 15px;
  padding-right: 15px;
  padding-top: 1px;
  padding-bottom: 1px;  
}
</style>

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

<body>

<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P0003R5</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2016-11-11</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Audience:</td>
  <td align="left">Core Working Group</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="#rev.hist">Revision History</a></li>
  <ul>
  <li><a href="#rev.0">Revision 0</a></li>
  <li><a href="#rev.1">Revision 1</a></li>
  <li><a href="#rev.2">Revision 2</a></li>
  <li><a href="#rev.3">Revision 3</a></li>
  <li><a href="#rev.4">Revision 4</a></li>
  <li><a href="#rev.5">Revision 5</a></li>
  </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">Review</a></li>
  <ul>
  <li><a href="#6.1">Evolution Working Group Review</a></li>
  <li><a href="#6.2">Design Choices</a></li>
  <li><a href="#6.3">Drafting Choices</a></li>
  <li><a href="#6.4">Considerations for Drafting Review</a></li>
  <li><a href="#6.5">Interaction with active issues</a></li>
  </ul>
<li><a href="#7.0">Proposed Wording</a></li>
  <ul>
  <li><a href="#STD_15.4">15.4 Exception specifications [except.spec]</a></li>
  <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_4.12">4.12 Function pointer conversions [conv.fctptr]</a></li>
  <li><a href="#STD_5.1.5">5.1.5 Lambda expressions [expr.prim.lambda]</a></li>
  <li><a href="#STD_5.3.7">5.3.7 noexcept operator [expr.unary.noexcept]</a></li>
  <li><a href="#STD_8.3.5">8 Declarators [dcl.decl]</a></li>
  <li><a href="#STD_8.3.5">8.3.5 Functions [dcl.fct]</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_12.1">12.1 Constructors [class.ctor]</a></li>
  <li><a href="#STD_12.4">12.4 Destructors [class.dtor]</a></li>
  <li><a href="#STD_12.5">12.5 Free store [class.free]</a></li>
  <li><a href="#STD_13.3.1.1.2">13.3.1.1.2 Call to object of class type [over.call.object]</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.8.2">14.8.2 Template argument deduction [temp.deduct]</a></li>
  <li><a href="#STD_15.3">15.3 Handling an exception [except.handle]</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.4.3.x">17.6.4.3.x Zombie names [zombie.names]:</li>
  <li><a href="#STD_17.6.4.7">17.6.4.7 Handler functions [handler.functions]</a></li>
  <li><a href="#STD_17.6.4.8">17.6.4.8 Other functions [res.on.functions]</a></li>
  <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.3">18.8.3 Class <tt>bad_exception</tt> [bad.exception]</a></li>
    </ul>
  <li><a href="#STD_23.3.7.8">23.3.7.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_C.2.6">C.2.6 Clause 12: special member functions [diff.cpp03.special]</a></li>
  <li><a href="#STD_C.4.x">C.4.x Clause 15: declarations [diff.cpp17.dcl.dcl]</a></li>
  <li><a href="#STD_D.3">D.3 Dynamic exception specifications [depr.except.spec]</a></li>
  <li><a href="#STD_D.6"><del>D.6 Violating <i>exception-specifications</i> [exception.unexpected]</del></a></li>
    <ul>
    <li><a href="#STD_D.6.1"><del>D.6.1 Type <tt>unexpected_handler</tt> [unexpected.handler]</del></a></li>
    <li><a href="#STD_D.6.2"><del>D.6.2 <tt>set_unexpected</tt> [set.unexpected]</del></a></li>
    <li><a href="#STD_D.6.3"><del>D.6.3 <tt>get_unexpected</tt> [get.unexpected]</del></a></li>
    <li><a href="#STD_D.6.4"><del>D.6.4 <tt>unexpected</tt> [unexpected]</del></a></li>
    </ul>
  </ul>
<li><a href="#8.0">Acknowledgements</a></li>
<li><a href="#9.0">References</a></li>
</ul>


<h2><a name="rev.hist">Revision History</a></h2>

<p>
A non-exhaustive list of changes through the revisions of this paper.
</p>

<h3><a name="rev.0">Revision 0</a></h3>
<p>
Original version of the paper for the 2015 pre-Kona mailing.
</p>

<h3><a name="rev.1">Revision 1</a></h3>
<p>
Revised the wording to modify the proposed working draft after the Kona 2015
meeting, N4567.  This accommodates renumbering a few clauses, notably Annex D
where several other features have already been removed, and allowing for
exception specifications in the type system, and the rewording of inheriting
constructors.
</p>

<h3><a name="rev.2">Revision 2</a></h3>
<p>
Changes for Jacksonville wording review:
</p>
<ul>
  <li>Fixed UTF8 marker for file-encoding</li>
  <li>Fix numerous typos</li>
  <li>Adopt simplified wording, rewriting the whole of clause <b>15.4 [except.spec]</b></li>
  <li>Define semantics consistently in the terms of <i>potentially-throwing</i> or
      <i>non-throwing</i> operations, rather than whether <i>exceptions are allowed</i></li>
  <li>Precise in usage of <i>exception-specification</i> vs. (plain) exception specification</li>
  <li>Provide list of zombie names</li>
  <li>(post meeting) Rebase wording off N4582, the post-meeting working paper</li>
  <li>(post meeting) Defer to issue 1343 to introduce definition for <i>immediate subexpression</i></li>
  <li>(post meeting) Address inconsistency in the older compatibility annex</li>
</ul>

<h3><a name="rev.3">Revision 3</a></h3>
<p>
Changes for Oulu wording review:
</p>
<ul>
  <li>Prefer &quot;function declarator&quot; to &quot;function declaration's declarator&quot;</li>
  <li>Exception specifications apply to a function type, not to a function</li>
  <li>Remove <del>deleted</del> text that referred to previous wording, rather than current working draft</li>
  <li>Simplify wording related to initializing base classes, and inheriting constructors</li>
  <li>Reordered and merged several pragraphs in new 15.4 wording</li>
  <li>Fix use of array-new in the example</li>
</ul>

<h3><a name="rev.4">Revision 4</a></h3>
<p>
Retargeted for C++Next-after-17.
</p>

<h3><a name="rev.5">Revision 5</a></h3>
<p>
Rebased the document on the C++17 CD:
<ul>
  <li>[conv.fctptr] is now 4.13, not 4.12</li>
  <li>[exception.unexpected] is now D.6, not D.5</li>
  <li>Renumbered footnotes 188-191 to 186-189</li>
  <li>Updated library use of <tt>typedef</tt> with type aliases</li>
  <li>Added parallel algorithms failing to list of reasons that terminate may be called</li>
  <li>Refer back to C++14 in Annex C (undo revision 4)</li>
</ul>
</p>
<p>
Revised the reworded [dcl.fct]p8 to make the newly simplified
<i>exception-specification</i> part of the function type.
</p>
<p>
Noted that this revision also resolves open Core issue 1644.
</p>

<ul>
  <li>
    Replace <i>exception-specification</i> grammar term with
    <i>noexcept-specifier</i>
  </li>
  <li>
    Apply proposed resolution for Core Issue 2191 directly to 15.4p6
  </li>
  <li>
    Add clear guidance that P0509 replaces the edits to [res.on.exception.handling]
    proposed by this document, if both papers are accepted
  </li>
  <li>
    Move all wording defining implicit defintion of an exception specification
    into the new clause 15.4
  </li>
  <li>
    numerous additional nits are raised and resolved during Core wording review
  </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
specifications, was deprecated,
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html">N3051</a>).
A new language 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/p0012r1">P0012R1</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 awkward
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 dynamic 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>
All wording dealing with <i>compatible</i> exception specifications, that used
to be described in terms of sets of permitted exceptions, has been redrafted
in terms of <i>potentially-throwing</i> and <i>non-throwing</i> operations and
exception specifications.  Eliminating the set-algebra significantly simplifies
the wording.
</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 language model (exceptions are key to understanding
constructors, destructors, and RAII) is an impediment that must be explained.
It remains embarrassing 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 grammar,
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/p0012r1">P0012R1</a>
goes 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
function 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 propagate, 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>

<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>
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>unexpected</tt> callback in a manner that is guaranteed to fail before the
subsequent call to <tt>terminate</tt>.  This paper proposes treating such
(still deprecated) 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
idiosyncrasies 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">Review</a></h2>

<h3><a name="6.1">Evolution Working Group Review</a></h3>
<p>
The first version of this paper was presented to the Evolution Working Group at
the Kona 2015 meeting, and was recommended to advance to Core 'as written'.
Specifically, that means retaining the empty exception specification as an
alternate spelling of <tt>noexcept(true)</tt>:
</p>
<table>
<tr>
  <td>SF</td>
  <td>WF</td>
  <td>N</td>
  <td>WA</td>
  <td>SA</td>
</tr>
<tr>
  <td>12</td>
  <td>13</td>
  <td>6</td>
  <td>0</td>
  <td>0</td>
</tr>
</table>

<h3><a name="6.2">Design Choices</a></h3>
<p>
By choosing to keep the <tt>throw()</tt> specification, we look to retain
source compatibility with a large body of existing code that has used this
specification to indicate code that should not throw.  However, we also
change the meaning of that specification to be exactly the same as a plain
<tt>noexcept</tt> specification, which means that an implementation is no
longer permitted to call <tt>unexpected</tt> when a violation is detected
(which was required in all previous standards) and the previously mandated
stack unwinding might no longer occur.  This means that a conforming C++20
implementation is not permitted to simply retain the C++17 semantics while
issuing an &quot;extension&quot; diagnostic.
</p>

<h3><a name="6.3">Drafting Choices</a></h3>
<p>
As the author is not a regular drafter of Core wording, a quick rationale
for some of the most obvious wording decisions seems helpful, especially
when drawing attention to changes that were deliberately <em>not</em> made.
</p>

<p>
Where there is some question over these decisions, it would probably be
more efficient to have direct feedback here, than sowing repeating detailed
comments throughout the wording - at least for the first round of review.
</p>

<del>
<h4>Retain the grammar production <i>exception-specification</i></h4>
<p>
To minimize the impact on the existing grammar and wording, the term
<i>exception-specification</i> is retained at exactly the same place in the
grammar.  However, it loses its ability to describe anything other than a
<i>noexcept-specification</i>.  The empty throw specification becomes a
(deprecated) synonym for <tt>noexcept(true)</tt>, and the
<i>noexcept-specification</i> production is retired.
</p>

<p>
An alternative formulation might have been to retire the original
<i>exception-specification</i> itself, forcing us to find and address each
existing use in the text - either to simply replace it with
<i>noexcept-specification</i>, or rewrite that part of the document to no
longer refer to exception specifications at all.
</p>

<p>
The author has gone with the first option as it will be a less disruptive set
of changes, and the Core working group has the expertise to spot and remove any
remaining redundancies as a later clean-up (if desired).
</p>
</del>

<ins>
<h4>Adopt the grammar production <i>noexcept-specifier</i></h4>
<p>
After repeated rounds of review, the subtle distinction between
<i>exception-specification</i> and non-italic &quot;exception
specification&quot; was causing more and more confusion.  It was recommended to
take the extra effort, and fully replace the grammar production
<i><del>exception-specification</del></i> with
<i><ins>noexcept-specifier</ins></i>.
</p>
</ins>

<h4>Simplify the specification from algebra on sets of types</h4>
<p>
The current text regarding exception specifications is written in terms of sets
of types that might pass through the specification, including the fictitious
notion of an &quot;any&quot; type.  With the removal of dynamic exception
specifications we can distill that down to a single bit.  Functions (and
expressions) either allow exceptions to propagate, or they do not.
</p>

<h4>With the removal of dynamic exception specifications, why not remove the
text for unwinding when an specification is violated?</h4>
<p>
The simple answer is that would be a technical change that needs to be
separately blessed by EWG.  The wording demanding unwinding at a violated
exception specification can be cleanly removed with the whole of sub-clause
15.5.2.  However, the implementation-defined choice on whether to unwind
through an <i>exception-specification</i> should remain, to support the
variety of exception unwinders deployed in production compilers today.
</p>

<h4>Exception specification vs. <i>exception-specification</i></h4>
<del>
<p>
During the wording review with the Core Working Group, it was confimed that
we wanted to be much more precise in the usage of the similar looking terms,
&quot;exception specification&quot; (in plain English), refers to the notion
of an exception specification, which may be implicit, while the italic term
<i>exception-specification</i> denotes exactly that grammar production and
its usage as such in source files.
</p>
</del>
<p>
This is moot now that the relevant grammar term is spelled
<i>noexcept-specifier</i>, and all such wording is clarified.
</p>


<h3><a name="6.4">Considerations for Drafting Review</a></h3>

<h4>Does the exception specification predicate tie into the grammar?</h4>
<p>
There is some concern that the new 15.4p1 does not quite tie in the new
definition for an exception specification predicate, to the grammar term that
is intended to produce the value for that predicate.
</p>

<del>
<h4>Did not touch wording that refers to types in exception specifications</h4>
<p>
There are a few clauses that talk about types when used in exception
specifications, such as describing the name look-up rules, or requirements for
type-completeness.  With the removal of
<i>dynamic-exception-specification</i>s, the first attempt at drafting updated
these clauses too.  However, in most or all cases, the existing text remains
valid, but more specific to exception specifications containing boolean
constant expressions.  The existing specification and notes in these paragraphs
now refer only to the contents of such expressions.
</p>
<p>
For reference (and review by the diligent) the list of clauses affected by
this decision to make no changes is:
</p>
<ul>
  <li>3.3.7    p1 bullet 1       [basic.scope.class]</li>
  <li>3.4.1    p7,8, footnote 31 [basic.lookup.unqual]</li>
  <li>9.2      p2                [class.mem]</li>
  <li>14.5     p2                [temp.decls]</li>
  <li>14.6     p11               [temp.res]</li>
  <li>14.6.4.1 p3                [temp.point]</li>
  <li>14.7.1   p1,12             [temp.inst]</li>
  <li>14.7.2   p12               [temp.explicit]</li>
  <li>14.8.2   p7                [temp.deduct]</li>
</ul>
<p>
Note that all cases above use the grammar term <i>exception-specification</i>
rather than the plain english &quot;exception specification&quot;.  In the
non-expert view of the author drafting the paper, that seems to be correct,
but would definitely be worth double-checking by a Core-drafting expert.
</p>
</del>

<h4>Clean up definition of &quot;immediate subexpression&quot;</h4>
<p>
The notion of an &quot;immediate subexpression&quot; will be more accurately
defined as part of the resolution for Core Issue 1343.  If that issue is
resolved at the same meeting that this paper is adopted, strike the two new
paragraphs 15.4p7,8.  The drafting below shows those paragraphs in a stike-
through font, so that the wording remains available should issue 1343 not be
ready to proceed at the same meeting.
</p>

<h4>Clean up C++03 Compatibility Annex</h4>
<p>
Several paragraphs in Annex C.2 refer to dynamic exception specifications in
ways that made sense for C++14, but are either no longer relevant or no
longer legal in C++17.
</p>

<h3><a name="6.5">Interaction with active issues</a></h3>
<ul>
  <li>Core issue 596: (Open) NAD as the subclause is eliminated</li>
  <li>Core issue 1644: (Open) Should be resolved in this paper's re-wording</li>
  <li>Core issue 2047: (WP) This paper totally rewrites the clause, eliminating the underlying issue</li>
  <li>Core issue 2183: (Open) Should be resolved in this paper's re-wording</li>
  <li></li>
  <li>Core issue 1912: (Extension) No direct impact</li>
  <li>Core issue 1934: (Extension) Redraft issue as underlying wording changes significantly</li>
</ul>


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

<p>
First, adopt the definition of <i>immediate subexpression</i> in clause
<b>1.9 [intro.execution]</b> from Core Issues 1343.
</p>

<p>
Replace the whole of clause 15.4 with:
</p>

<blockquote>

<h4><a name="STD_15.4">15.4 Exception specifications [except.spec]</a></h4>
<ol>
<li><ins>
The predicate indicating whether a function cannot exit via an exception is
called the <i>exception specification</i> of the function.  If the predicate is
false, the function has a <i>potentially-throwing exception specification</i>,
otherwise it has a <i>non-throwing exception specification</i>.  The exception
specification is either defined implicitly, or defined explicitly by using a
<i>noexcept-specifier</i> as a suffix of a function declarator (8.3.5).
</ins></li>
<pre>
   <ins><i>noexcept-specifier:</i></ins>
      <ins>noexcept ( <i>constant-expression</i> )</ins>
      <ins>noexcept</ins>
      <ins>throw ( )</ins>
</pre>

<li><ins>
In a <i>noexcept-specifier</i>, the <i>constant-expression</i>, if supplied,
shall be a contextually converted constant expression of type <tt>bool</tt>
(5.20 [expr.const]); that constant expression is the exception specification of
the function type in which the <i>noexcept-specifier</i> appears.  A <tt>(</tt>
token that follows <tt>noexcept</tt> is part of the <i>noexcept-specifier</i>
and does not commence an initializer (8.5).  The <i>noexcept-specifier</i>
<tt>noexcept</tt> without a <i>constant-expression</i> is equivalent to the
<i>noexcept-specifier</i> <tt>noexcept(true)</tt>.  The
<i>noexcept-specifier</i> <tt>throw()</tt> is deprecated (D.3), and equivalent
to the <i>noexcept-specifier</i> <tt>noexcept(true)</tt>.
</ins></li>

<li><ins>
If a declaration of a function does not have a <i>noexcept-specifier</i>, the
declaration has a potentially throwing exception specification unless it is a
destructor or a deallocation function or is defaulted on its first declaration,
in which cases the exception specfication is as specified below and no other
declaration for that function shall have a <i>noexcept-specifier</i>.  In an
explicit instantiation (14.7.2) a <i>noexcept-specifier</i> may be specified,
but is not required. If a <i>noexcept-specifier</i> is specified in an explicit
instantiation directive, the exception specification shall be the same as the
exception specification of all other declarations of that function.  A
diagnostic is required only if the exception specifications are not the same
within a single translation unit.
</ins></li>

<li><ins>
If a virtual function has a non-throwing exception specification, all
declarations, including the definition, of any function that overrides that
virtual function in any derived class shall have a non-throwing exception
specification, unless the overriding function is defined as deleted. [
<i>Example:</i>
</ins></li>
<pre>
     <ins>struct B {</ins>
       <ins>virtual void f() noexcept;</ins>
       <ins>virtual void g();</ins>
       <ins>virtual void h() noexcept = delete;</ins>
     <ins>};</ins>

     <ins>struct D: B {</ins>
       <ins>void f();              <i>// ill-formed</i></ins>
       <ins>void g() noexcept;     <i>// OK</i></ins>
       <ins>void h() = delete;     <i>// OK</i></ins>
     <ins>};</ins>
</pre>
<p><ins>
The declaration of <tt>D::f</tt> is ill-formed because it has a
potentially-throwing exception specification, whereas <tt>B::f</tt> has a
non-throwing exception specification. &mdash;
<i>end example</i>]
</ins></p>

<li><ins>
Whenever an exception is thrown and the search for a handler (15.3) encounters
the outermost block of a function with a non-throwing exception specification,
the function <tt>std::terminate()</tt> is called (15.5.1).  [ <i>Note:</i> An
implementation shall not reject an expression merely because, when executed, it
throws or might throw an exception from a function with a non-throwing
exception specification.  &mdash; <i>end note</i> ] [ <i>Example:</i>
</ins></p>
<pre>
     <ins>extern void f();  <i>// potentially-throwing</i></ins>
     <ins>void g() noexcept {</ins>
       <ins>f();      <i>// valid, even if f throws</i></ins>
       <ins>throw 42; <i>// valid, effectively a call to <tt>std::terminate</tt></i></ins></ins>
     <ins>}</ins>
</pre>
<p><ins>
the call to <tt>f</tt> is well-formed even though, when called, <tt>f</tt>
might throw an exception. &mdash; <i>end
example</i> ]
</ins></li>

<li><ins>
An expression <tt>e</tt> is <i>potentially-throwing</i> if
</ins></p>
<ol>
<li><ins>
<tt>e</tt> is function call whose <i>postfix-expression</i> (5.2.2) has a
function type, or a pointer-to-function type, with a potentially-throwing
exception specification, or
</ins></li>
<li><ins>
<tt>e</tt> implicitly invokes a function (such as an overloaded operator, an
allocation function in a <i>new-expression</i>, a constructor for a function
argument, or a destructor if <tt>e</tt> is a full-expression (1.9)) that is
potentially-throwing, or
</ins></li>
<li><ins>
<tt>e</tt> is a <i>throw-expression</i> (5.17), or
</ins></li>
<li><ins>
<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), or
</ins></li>
<li><ins>
<tt>e</tt> is a <tt>typeid</tt> expression applied to a (possibly
parenthesized) built-in unary * operator applied to a pointer to a polymorphic
class type (5.2.8), or
</ins></li>
<li><ins>
any of the immediate subexpressions (1.9) of <tt>e</tt> is potentially-throwing.
</ins></li>
</ol>

<li><ins>
An implicitly-declared constructor for a class <tt>X</tt>,  or a constructor
without a <i>noexcept-specifier</i> that is defaulted on its first declaration,
has a potentially-throwing exception specification if and only if any of the
following constructs is potentially-throwing:
<ul>
<li>
a constructor selected by overload resolution in the implicit definition of the
constructor for class <tt>X</tt> to initialize a potentially constructed
subobject, or
</li>
<li>
a subexpression of such an initialization, such as a default argument
expression, or,
</li>
<li>
for a default constructor, a default member initializer.
</li>
</ul>

</li>

<li><ins>
[ <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 would call <tt>std::terminate</tt> rather than escape the
constructor (15.1, 15.5.1). &mdash; <i>end note</i>]
</ins></li>

<li><ins>
The exception specification for an implicitly-declared destructor, or a
destructor without a <i>noexcept-specifier</i>, is potentially-throwing if and
only if any of the destructors for any of its potentially constructed subojects
is potentially throwing.
</ins></li>

<li><ins>
The exception specification for an implicitly-declared assignment operator, or
an assignment-operator without a <i>noexcept-specifier</i> that is defaulted on
its first declaration, is potentially-throwing if and only if the invocation of
any assignment operator in the implicit definition is potentially-throwing.
</ins></li>

<li><ins>
A deallocation function (3.7.4.2) with no explicit <i>noexcept-specifier</i>
has a non-throwing exception specification.
</ins></li>

<li><ins>[ <i>Example:</i></ins>
<pre>
   <ins>struct A {</ins>
     <ins>A(int = (A(5), 0)) noexcept;</ins>
     <ins>A(const A&amp;) noexcept;</ins>
     <ins>A(A&amp;&amp;) noexcept;</ins>
     <ins>~A();</ins>
   <ins>};</ins>
   <ins>struct B {</ins>
     <ins>B() throw();</ins>
     <ins>B(const B&amp;) = default;  <i>// implicit exception specification is <tt>noexcept(true)</tt></i></ins>
     <ins>B(B&amp;&amp;, int = (throw Y(), 0)) noexcept;</ins>
     <ins>~B() noexcept(false);</ins>
   <ins>};</ins>
   <ins>int n = 7;</ins>
   <ins>struct D : public A, public B {</ins>
     <ins>int * p = new int[n];</ins>
     <ins><i>// D::D() potentially-throwing, as the new operator may throw <tt>bad_alloc</tt> or <tt>bad_array_new_length</tt></i></ins>
     <ins><i>// D::D(const D&amp;) non-throwing</i></ins>
     <ins><i>// D::D(D&amp;&amp;) potentially-throwing, as the default argument for B's constructor may throw</i></ins>
     <ins><i>// D::~D() potentially-throwing</i></ins>
   <ins>};</ins>
</pre>
<p><ins>
Furthermore, if <tt>A::~A()</tt> were virtual, the program would be ill-formed
since a function that overrides a virtual function from a base class shall not
have a potentially-throwing exception specification if the base class function
has a non-throwing exception specification. &mdash; <i>end example</i> ]
</ins></li>

<li><ins>
An exception specification is considered to be <i>needed</i> when:

<ol>
<li>
&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);
</li>
<li>
&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;
</li>
<li>
&mdash; the exception specification is compared to that of another declaration
(e.g., an explicit specialization or an overriding virtual function);
</li>
<li>
&mdash; the function is defined; or
</li>
<li>
&mdash; the exception specification is needed for a defaulted special member
function that calls the function. [ <i>Note:</i> A defaulted declaration does
not require the exception specification of a base member function to be
evaluated until the implicit exception specification of the derived function is
needed, but an explicit <i>noexcept-specifier</i> needs the implicit
exception specification to compare against.  &mdash;
<i>end note</i> ]
</li>
</ol>

The exception specification of a defaulted special member function is evaluated
as described above only when needed; similarly, the
<i>noexcept-specifier</i> of a specialization of a function template or
member function of a class template is instantiated only when needed.
</ins></li>
</ol>
</blockquote>


<p>
And make the following additional changes to the working draft:
</p>

<blockquote>

<h4><a name="STD_3.3.7">3.3.7 Class scope [basic.scope.class]</a></h4>
<p>
1 The following rules describe the scope of names declared in classes.
</p>
<blockquote>
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,
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i>s,
and <i>brace-or-equal-initializers</i> of non-static data members in that class
(including such things in nested classes).
</blockquote>


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

<p>...</p>

<p>
8 For the members of a class <tt>X</tt>, a name used in a member function body,
in a default argument, in a<del>n <i>exception-specification</i></del>
<ins><i>noexcept-specifier</i></ins>, 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><sup>31</sup>, shall be declared in one of the following
ways:
</p>

<h4><a name="STD_4.12">4.13 Function pointer conversions [conv.fctptr]</a></h4>
<p>
1 A prvalue of type “pointer to <tt>noexcept</tt> function” can be converted to
a prvalue of type “pointer to function”. The result is a pointer to the
function.  A prvalue of type “pointer to member of type <tt>noexcept</tt>
function” can be converted to a prvalue of type “pointer to member of type
function”. The result points to the member function.
[ <i>Example:</i>
<blockquote><pre>
void (*p)() <del>throw(int)</del>;
void (**pp)() noexcept = &p; <i>// error: cannot convert to pointer to noexcept function</i>

struct S { typedef void (*p)(); operator p(); };
void (*q)() noexcept = S(); <i>// error: cannot convert to pointer to noexcept function</i>
</pre></blockquote>
&mdash; <i>end example</i> ]


<h4><a name="STD_5.1.5">5.1.5 Lambda expressions [expr.prim.lambda]</a></h4>
<blockquote><pre><i>
lambda-expression:
    lambda-introducer lambda-declarator<sub>opt</sub> compound-statement
lambda-introducer:
    [ lambda-capture<sub>opt</sub> ]
lambda-capture:
    capture-default
    capture-list
    capture-default , capture-list
capture-default:
    &amp;
    =
capture-list:
    capture ...<sub>opt</sub>
    capture-list , capture ...<sub>opt</sub>
capture:
    simple-capture
    init-capture
simple-capture:
    identifier
    &amp; identifier
    this
    * this
init-capture:
    identifier initializer
    &amp; identifier initializer
lambda-declarator:
    ( parameter-declaration-clause ) decl-specifier-seq<sub>opt</sub>
        <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub> trailing-return-type<sub>opt</sub>
</i></pre></blockquote>
<p>
6 The closure type for a non-generic <i>lambda-expression</i> has... 
</p>
<p>
[ <i>Example</i> ... &mdash; <i>end example</i> ] This function call operator
or operator template is declared <tt>const</tt> (9.2.2) if and only if the
<i>lambda-expression</i>'s <i>parameter-declaration-clause</i> is not followed
by <tt>mutable</tt>. It is neither virtual nor declared <tt>volatile</tt>. Any
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i> specified
on a <i>lambda-expression</i> applies to the corresponding function call
operator or operator template. ...
</p>

<h4><a name="STD_5.3.7">5.3.7 noexcept operator [expr.unary.noexcept]</a></h4>
<p>
1 The <tt>noexcept</tt> operator determines whether the evaluation of its operand, which
is an unevaluated operand (Clause 5), can throw an exception (15.1).
</p>
<blockquote>
<i>noexcept-expression:</i>
<blockquote>
<tt>noexcept</tt> ( <i>expression</i> )
</blockquote>
</blockquote>
<p>
2 The result of the <tt>noexcept</tt> operator is a constant of type
<tt>bool</tt> and is a prvalue.
</p>
<p>
3 The result of the <tt>noexcept</tt> operator is <tt>true</tt> <ins>unless the
<i>expression</i> is potentially-throwing (15.4)</ins><del> if the set of
potential exceptions of the expression (15.4) is empty, and <tt>false</tt>
otherwise</del>.
</p>


<h4><a name="STD_8.3.5">8 Declarators [dcl.decl]</a></h4>
<p>
4 Declarators have the syntax
<blockquote><pre><i>
declarator:
    ptr-declarator
    noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator:
    noptr-declarator
    ptr-operator ptr-declarator
noptr-declarator:
    declarator-id attribute-specifier-seq<sub>opt</sub>
    noptr-declarator parameters-and-qualifiers
    noptr-declarator [ constant-expression<sub>opt</sub> ] attribute-specifier-seq<sub>opt</sub>
    ( ptr-declarator )
parameters-and-qualifiers:
   ( parameter-declaration-clause ) cv-qualifier-seq<sub>opt</sub>
       ref-qualifier<sub>opt</sub> <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub>
trailing-return-type:
    -> type-id
ptr-operator:
    *attribute-specifier-seq<sub>opt</sub> cv-qualifier-seq<sub>opt</sub>
    &amp; attribute-specifier-seq<sub>opt</sub>
    &amp;&amp; attribute-specifier-seq<sub>opt</sub>
    nested-name-specifier * attribute-specifier-seq<sub>opt</sub> cv-qualifier-seq<sub>opt</sub>
cv-qualifier-seq:
    cv-qualifier cv-qualifier-seq<sub>opt</sub>
cv-qualifier:
    </i>const
    volatile<i>
ref-qualifier:
    </i>&amp;
    &amp;&amp;<i>
declarator-id:
    ...<sub>opt</sub> id-expression
</i></pre></blockquote>
</p>

<h4><a name="STD_8.3.5">8.3.5 Functions [dcl.fct]</a></h4>
<p>
1 In a declaration <tt>T D</tt> where <tt>D</tt> has the form
<pre><blockquote>
 D1 ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub></i>
      <i>ref-qualifier<sub>opt</sub> <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub></i>
</blockquote></pre>
and the type of the contained <i>declarator-id</i> in the declaration <tt>T
D1</tt> is “<i>derived-declarator-type-list</i> <tt>T</tt>”, the type of the
<i>declarator-id</i> in <tt>D</tt> is “<i>derived-declarator-type-list</i>
<tt>noexcept</tt><i><sub>opt</sub></i> function of
(<i>parameter-declaration-clause</i>) <i>cv-qualifier-seq<sub>opt</sub>
ref-qualifier<sub>opt</sub></i> returning <tt>T</tt>”, where the optional
<tt>noexcept</tt> is present if and only if the
<del><i>exception-specification</i></del><ins>exception specification</ins>
(15.4) is non-throwing. The optional <i>attribute-specifier-seq</i> appertains
to the function type.
</p>

<p>
2 In a declaration <tt>T D</tt> where <tt>D</tt> has the form
<pre><blockquote>
 D1 ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub></i>
      <i>ref-qualifier<sub>opt</sub> <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub> trailing-return-type</i>
</blockquote></pre>
and the type of the contained <i>declarator-id</i> in the declaration <tt>T
D1</tt> is “<i>derived-declarator-type-list</i> <tt>T</tt>”, <tt>T</tt> shall
be the single <i>type-specifier</i> <tt>auto</tt>.  The type of the
<i>declarator-id</i> in <tt>D</tt> is “<i>derived-declarator-type-list</i>
<tt>noexcept</tt><i><sub>opt</sub></i> function of
(<i>parameter-declaration-clause</i>) <i>cv-qualifier-seq<sub>opt</sub>
ref-qualifier<sub>opt</sub></i> returning <tt>U</tt>”, where <tt>U</tt> is the
type specified by the <i>trailing-return-type</i>, and where the optional
<tt>noexcept</tt> is present if and only if the
<del><i>exception-specification</i></del><ins>exception specification</ins>
(15.4) is non-throwing. The optional <i>attribute-specifier-seq</i> appertains
to the function type.
</p>

<p>
8 The return type, the parameter-type-list, the <i>ref-qualifier</i>, the
<i>cv-qualifier-seq</i>, and <del>whether the function has a non-throwing
<i>exception-specification</i></del><ins> the exception specification</ins>,
but not the default arguments (8.3.6) <del>or the exception specification
(15.4)</del>, are part of the function type.  [<i>Note:</i> Function types are
checked during the assignments and initializations of pointers to functions,
references to functions, and pointers to member functions. &mdash; <i>end
note</i> ]
</p>

<h4><a name="STD_8.4.2">8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]</a></h4>
<!-- Extension issue 1912 proposes restricting in only one direction -->
<p>
2 An explicitly-defaulted function that is not defined as deleted may be
declared <tt>constexpr</tt> only if it would have been implicitly declared as
<tt>constexpr</tt>.  If a function is explicitly defaulted on its first
declaration, <ins>it is implicitly considered to be <tt>constexpr</tt> if the
implicit declaration would be.</ins>
</p>
<del><ol>
  <li>&mdash; it is implicitly considered to be <tt>constexpr</tt> if the implicit declaration would be, and,</li>
  <li>&mdash; it has the same exception specification as if it had been implicitly declared (15.4).</li>
</ol></del>
<p>
3 If a function that is explicitly defaulted is declared with a<del>n
<i>exception-specification</i></del><ins><i>noexcept-specifier</i></ins> that
<del>is not compatible (15.4) with</del><ins>does not produce</ins> the
<ins>same</ins> exception specification <del>of</del><ins>as</ins> the implicit
declaration<ins>(15.4)</ins>, then
</p>
<p>
(3.1) &mdash; if the function is explicitly defaulted on its first declaration,
it is defined as deleted;
</p>
<p>
(3.2) &mdash; otherwise, the program is ill-formed.
</p>
<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>


<h4><a name="STD_9.2">9.2 Class members [class.mem]</a></h4>
<p>
6 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><del>exception-specification</del><ins>noexcept-specifier</ins></i>s, and
default member initializers (including such things in nested classes).
Otherwise it is regarded as incomplete within its own class
<i>member-specification</i>.
</p>

<p>
8 A <i>brace-or-equal-initializer</i> shall appear only in the declaration of a data
member. (For static data members, see 9.2.3.2; for non-static data members, see
12.6.2 and 8.6.1). A <i>brace-or-equal-initializer</i> for a non-static data member
specifies a <i>default member initializer</i> for the member, and shall not directly
or indirectly cause the implicit definition of a defaulted default constructor
for the enclosing class or the exception specification of that constructor.
</p>


<h4><a name="STD_12.1">12.1 Constructors [class.ctor]</a></h4>
<p>
1 Constructors do not have names. In a declaration of a constructor, the
declarator is a function declarator (8.3.5) of the form
<blockquote><i>
ptr-declarator </i><tt>(</tt><i> parameter-declaration-clause </i><tt>)</tt><i> <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub>
</i></blockquote>
</p>

<h4><a name="STD_12.4">12.4 Destructors [class.dtor]</a></h4>
<p>
1 In a declaration of a destructor, the declarator is a function declarator (8.3.5) of the form
<blockquote><i>
ptr-declarator </i><tt>(</tt><i> parameter-declaration-clause </i><tt>)</tt><i> <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub>
</i></blockquote>
where the <i>ptr-declarator</i> consists solely of an <i>id-expression</i>, an optional
<i>attribute-specifier-seq</i>, and optional surrounding parentheses, and the
<i>id-expression</i> has one of the following forms:
</p>

<p>...</p>

<p>
3 <ins>[ <i>Note:</i> </ins>A declaration of a destructor that does not have
a<del>n
<i>exception-specification</i></del><ins><i>noexcept-specifier</i></ins> has
the same exception specification as if had been implicitly declared (15.4).
<ins>&mdash; <i>end note</i> ]</ins>
</p>


<h4><a name="STD_12.5">12.5 Free store [class.free]</a></h4>
<p>
8 [ <i>Note:</i> If a deallocation function has no explicit
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i>, it has
a non-throwing exception specification(15.4). &mdash; <i>end note</i> ]
</p>


<h4><a name="STD_13.3.1.1.2">13.3.1.1.2 Call to object of class type [over.call.object]</a></h4>
<p>
2 In addition, for each non-explicit conversion function declared in <tt>T</tt> of the form
<blockquote>
<tt>operator</tt> <i>conversion-type-id</i> <tt>()</tt> <i>cv-qualifier ref-qualifier<sub>opt</sub> <del>exception-specification</del><ins>noexcept-specifier</ins><sub>opt</sub> attribute-specifier-seq<sub>opt</sub></i> <tt>;</tt>
</blockquote>
</p>

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

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


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


<h4><a name="STD_14.6.4.1">14.6.4.1 Point of instantiation [temp.point]</a></h4>
<p>
3 For an <i><del>exception-specification</del><ins>noexcept-specifier</ins></i>
of a function template specialization or specialization of a member function of
a class template, if the
<i><del>exception-specification</del><ins>noexcept-specifier</ins></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><del>exception-specification</del><ins>noexcept-specifier</ins></i> is the
point of instantiation of the specialization that requires it.  Otherwise, the
point of instantiation for such an
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i>
immediately follows the namespace scope declaration or definition that requires
the <i><del>exception-specification</del><ins>noexcept-specifier</ins></i>.
</p>


<h4><a name="STD_14.7.1">14.7.1 Implicit instantiation [temp.inst]</a></h4>
<p>
1 Unless a class template specialization has ...
</p>
<p>
[ <i>Example:</i> ... &mdash; <i>end example</i> ]
If a class template has been declared, but not defined, at the point of instantiation (14.6.4.1),
the instantiation yields an incomplete class type (3.9). [ <i>Example:</i> 
<blockquote><pre>
template&lt;class T&gt; class X;
X&lt;char&gt; ch; <i>// error: incomplete type &lt;char&gt;</i>
</pre></blockquote>
&mdash; <i>end example</i> ]
[ <i>Note:</i> Within a template declaration, a local class (9.4) 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,
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i>s, 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, default
arguments, or
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i>s 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>...</p>

<p>
12 The <i><del>exception-specification</del><ins>noexcept-specifier</ins></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><del>exception-specification</del><ins>noexcept-specifier</ins></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><del>exception-specification</del><ins>noexcept-specifier</ins></i> is done
as if it were being done as part of instantiating the declaration of the
specialization at that point.
</p>

<h4><a name="STD_14.8.2">14.8.2 Template argument deduction [temp.deduct]</a></h4>
<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. [
<i>Note:</i> The equivalent substitution in exception specifications is done
only when the
<i><del>exception-specification</del><ins>noexcept-specifier</ins></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>] [
<i>Example:</i>
</p>
<p>...</p>

<h4><a name="STD_15.3">15.3 Handling an exception [except.handle]</a></h4>
<p>
7 A handler is considered active when initialization is complete for the
parameter (if any) of the catch clause. [ <i>Note:</i> The stack will have been
unwound at that point. &mdash; <i>end note</i> ] Also, an implicit handler is
considered active when <tt>std::terminate()</tt> <del>or
<tt>std::unexpected()</tt></del> is entered due to a throw. A handler is no
longer considered active when the catch clause exits<del> or when
<tt>std::unexpected()</tt> exits after being entered due to a throw</del>.
</p>


<h4><a name="STD_15.5">15.5 Special functions [except.special]</a></h4>
<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.6) and the class <tt>std::nested_exception</tt> (18.8.7) can be used by a
program to capture the currently handled exception.
</p>

<h4><a name="STD_15.5.1">15.5.1 The std::terminate() function [except.terminate]</a></h4>
<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>non-throwing
exception specification</ins> <del><i>noexcept-specification</i> that
does not allow the exception</del> (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.3) 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.4), 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.6.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.7), 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 execution of an element access function (25.2.1) of a
parallel algorithm exits via an exception (25.2.4), or
</p>
<p>
(1.14) &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.15) &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.4). 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>non-throwing exception specification</ins>
<del><i>noexcept-specification</i> that does not allow the exception</del>
(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>


<h4><a name="STD_15.5.2"><del>15.5.2 The <tt>std::unexpected()</tt> function [except.unexpected]</del></a></h4>
<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.6) 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.6.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.3) 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>


<h4><a name="STD_17.6.4.3.x">17.6.4.3.1 Zombie names [zombie.names]:</h4>
<ol>
<li>
In namespace <tt>std</tt>, the following names are reserved for previous standardization:
  <tt>auto_ptr</tt>,
  <tt>binary_function</tt>,
  <tt>bind1st</tt>,
  <tt>bind2nd</tt>,
  <tt>binder1st</tt>,
  <tt>binder2nd</tt>,
  <tt>const_mem_fun1_ref_t</tt>,
  <tt>const_mem_fun1_t</tt>,
  <tt>const_mem_fun_ref_t</tt>,
  <tt>const_mem_fun_t</tt>,
  <ins><tt>get_unexpected</tt>,</ins>
  <tt>mem_fun1_ref_t</tt>,
  <tt>mem_fun1_t</tt>,
  <tt>mem_fun_ref</tt>,
  <tt>mem_fun_ref_t</tt>,
  <tt>mem_fun_t</tt>,
  <tt>mem_fun</tt>,
  <tt>pointer_to_binary_function</tt>,
  <tt>pointer_to_unary_function</tt>,
  <tt>ptr_fun</tt>,
  <tt>random_shuffle</tt>,
  <ins><tt>set_unexpected</tt>,</ins> <del>and</del>
  <tt>unary_function</tt><del>,</del><ins>,</ins>
  <ins><tt>unexpected</tt>,
  and <tt>unexpected_handler</tt>.</ins>
</li>
</ol>


<h4><a name="STD_17.6.4.7">17.6.4.7 Handler functions [handler.functions]</a></h4>
<p>
1 The C++ standard library provides <ins>a</ins> default version<del>s</del> of
the following handler function<del>s</del> (Clause 18):
</p>
<p><del>
(1.1) &mdash; <tt>unexpected_handler</tt>
</del></p>
<p>
(1.2) &mdash; <tt>terminate_handler</tt>
</p>

<p>
2 A C++ program may install different handler functions during execution, by
supplying a pointer to a function defined in the program or the library as an
argument to (respectively):
</p>
<p>
(2.1) &mdash; <tt>set_new_handler</tt>
</p>
<p><del>
(2.2) &mdash; <tt>set_unexpected</tt>
</del></p>
<p>
(2.3) &mdash; <tt>set_terminate</tt>
</p>
<p>
See also: subclauses 18.6.3, Storage allocation errors, and 18.8, Exception handling.
</p>

<p>
3 A C++ program can get a pointer to the current handler function by calling
the following functions:
</p>
<p>
(3.1) &mdash; <tt>get_new_handler</tt>
</p>
<p><del>
(3.2) &mdash; <tt>get_unexpected</tt>
</del></p>
<p>
(3.3) &mdash; <tt>get_terminate</tt>
</p>

<p>
4 Calling the <tt>set_*</tt> and <tt>get_*</tt> functions shall not incur a
data race. A call to any of the <tt>set_*</tt> functions shall synchronize with
subsequent calls to the same <tt>set_*</tt> function and to the corresponding
<tt>get_*</tt> function.
</p>


<h4><a name="STD_17.6.4.8">17.6.4.8 Other functions [res.on.functions]</a></h4>
<p>
(2.2) &mdash; for handler functions (18.6.3.3, 18.8.4.1<del>, D.6.1</del>), if the
installed handler function does not implement the semantics of the applicable
<i>Required behavior:</i> paragraph<ins>.</ins>
</p>


<h4><a name="STD_17.6.5.12">17.6.5.12 Restrictions on exception handling [res.on.exception.handling]</a></h4>
<blockquote class="note">
It is expected that P0509 will be adopted at the same meeting as this paper, in
which case P0509 provides a complete replacement for the text of this clause,
and should be used instead.
</blockquote>

<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.
<del>An implementation may strengthen the exception specification for a
non-virtual function by adding a non-throwing
<i>noexcept-specification</i>.</del>
</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<sup>186</sup> except when such a function calls a program-supplied
function that throws an exception.<sup>187</sup>
</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 defined in the
C++ standard library that do not have a<del>n</del>
<i><del>exception-specification</del><ins>noexcept-specifier</ins></i> may
throw implementation-defined exceptions unless otherwise
specified.<sup>188</sup> <del>An implementation may strengthen this implicit
<i>exception-specification</i> by adding an explicit
one</del>.<sup><del>189</del></sup>
</p>
<p><ins>
5 An implementation may strengthen the exception specification for a non-virtual
function by adding a non-throwing exception specification.
</ins></p>
<p><del>
189) 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>

<h4><a name="STD_18.8">18.8 Exception Handling [support.exception]</a></h4>
<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>
<blockquote><pre>
namespace std {
  class exception;
  class bad_exception;
  class nested_exception;

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

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

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

  using exception_ptr = <i>unspecified</i>;

  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></blockquote>


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


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


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

<h3><a name="STD_C.2.6">C.2.6 Clause 12: special member functions [diff.cpp03.special]</a></h3>

<p>12.4 (destructors)</p>
<p>
<b>Change:</b> User-declared destructors have an implicit exception specification.
</p>
<p>
<b>Rationale:</b> Clarification of destructor requirements.
</p>
<p>
<b>Effect on original feature:</b>Valid C++ 2003 code may execute differently
in this International Standard. In particular, destructors that throw
exceptions will call <tt>std::terminate()</tt> (without calling
<tt>std::unexpected()</tt>) if their exception specification <ins>is
non-throwing</ins><del>is <tt>noexcept</tt> or <tt>noexcept(true)</tt>.  For a
throwing virtual destructor of a derived class, <tt>std::terminate()</tt> can
be avoided only if the base class virtual destructor has an exception
specification that is not <tt>noexcept</tt> and not
<tt>noexcept(true)</tt></del>.
</p>

<h3><ins><a name="STD_C.4.x">C.4.x Clause 15: Exception handling [diff.cpp14.except]</a></ins></h3>

<p><ins>15.4</ins></p>
<p><ins>
<b>Change:</b> Remove dynamic exception specifications.
</ins></p>
<p><ins>
<b>Rationale:</b> Dynamic exception specifications were a deprecated
feature that was complex and brittle in use.  They interacted badly with the
type system, which became a more significant issue in this International
Standard where (non-dynamic) exception specifications became part of the
function type.
</ins></p>
<p><ins>
<b>Effect on original feature:</b> A valid C++ 2014 function declaration,
member function declaration, function pointer declaration, or
function reference declaration, if it has a potentially throwing dynamic
exception specification, will be rejected as ill-formed in this International
Standard.  Violating a non-throwing dynamic exception specification will call
<tt>terminate</tt> rather than <tt>unexpected</tt> and might not perform stack
unwinding prior to such a call.
</ins></p>

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


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

<h4><a name="STD_D.6.1"><del>D.6.1 Type <tt>unexpected_handler</tt> [unexpected.handler]</del></a></h4>
<p><del>
<tt>using unexpected_handler = void (*)();</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>

<h4><a name="STD_D.6.2"><del>D.6.2 <tt>set_unexpected</tt> [set.unexpected]</del></a></h4>
<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>

<h4><a name="STD_D.6.3"><del>D.6.3 <tt>get_unexpected</tt> [get.unexpected]</del></a></h4>
<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>

<h4><a name="STD_D.6.4"><del>D.6.4 <tt>unexpected</tt> [unexpected]</del></a></h4>
<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.6.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>

</blockquote>


<h2><a name="8.0">Acknowledgements</a></h2>
<p>
Thanks to Jens Maurer for the initial review, identifying a number of proposed
edits that had unintended consequences.  Huge thanks to the Core working group
for a patient and thorough review that signicantly improved the clarify of the
final text.
</p>


<h2><a name="9.0">VIII. References</a></h2>
<ul>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0741">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">N3051</a> Deprecating Exception Specifications, Doug Gregor</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/p0001r1">P0001R1</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/p0002r1">P0002R1</a> Remove Deprecated <tt>operator++(bool)</tt></li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0004r1">P0004R1</a> Remove Deprecated iostreams aliases</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1">P0012R1</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/2016/p0509r1">P0509R1</a> Updating “Restrictions on exception handling”, James Dennet</li>
</ul>

</body>
</html>
