<!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">P0003R1</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2016-02-09</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="#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">Interaction with issues</a></li>
  <li><a href="#6.4">Drafting Choices</a></li>
</ul>
<li><a href="#7.0">Proposed Wording</a></li>
<ul>
  <li><a href="#7.1">First cut, using current set-based 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_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.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_4.12">4.12 Function pointer conversions [conv.fctptr]</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_14.5.3">14.5.3 Variadic templates [temp.variadic]</a></li>
    <li><a href="#STD_15.3">15.3 Handling an exception [except.handle]</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.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.4.x">C.4.x Clause 15: declarations [diff.cpp14.dcl.dcl]</a></li>
    <li><a href="#STD_D.2">D.2 Dynamic exception specifications [depr.except.spec]</a></li>
    <li><a href="#STD_D.5">D.5 Violating <i>exception-specifications</i> [exception.unexpected]</a></li>
    <ul>
      <li><a href="#STD_D.5.1">D.5.1 Type <tt>unexpected_handler</tt> [unexpected.handler]</a></li>
      <li><a href="#STD_D.5.2">D.5.2 <tt>set_unexpected</tt> [set.unexpected]</a></li>
      <li><a href="#STD_D.5.3">D.5.3 <tt>get_unexpected</tt> [get.unexpected]</a></li>
      <li><a href="#STD_D.5.4">D.5.4 <tt>unexpected</tt> [unexpected]</a></li>
    </ul>
  </ul>
  <li><a href="#7.2">Second cut: simplified wording</li>
  <ul>
    <li><a href="#STD.2_5.3.7">5.3.7 noexcept operator [expr.unary.noexcept]</a></li>
    <li><a href="#STD.2_8.4.2">8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]</a></li>
    <li><a href="#STD.2_15.4">15.4 Exception specifications [except.spec]</a></li>
  </ul>
</ul>
<li><a href="#8.0">Acknowledgements</a></li>
<li><a href="#9.0">References</a></li>
</ul>


<h2><a name="0.0">Revision History</a></h2>

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

<h3><a name="0.2">Revision 1</a></h3>
<p>
Revised the wording to modify the proposed working draft after the Kona 2015
meeting, N4567.  This accmodates 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>

<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">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 mnadated
stack unwinding might no longer occur.  This means that a conforming C++17
implementation is not permitted to simply retain the C++14 semantics while
issuing an &quot;extension&quot; diagnostic.
</p>

<h3><a name="6.3">Interaction with issues</a></h3>
<ul>
  <li>Core issue 596: (Open) NAD as the subclause is eliminated</li>
  <li>Core issue 1604: (wrong issue number, lost my reference?)</li>
  <li>Core issue 2039: (Tentatively Ready) Proposed resolution should apply on top of this wording</li>
  <li>Core issue 2047: (Ready) Proposed resolution incorporated into wording</li>
  <li>Core issue 2183: (Open) Must 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>

<h3><a name="6.4">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>

<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 formuation 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 distruptive 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>


<h4>Retain the specification in terms of 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.  This drafting removes the
notion of an &quot;any&quot; type, and simplifies the world down to two sets:
the empty set, and the set of all types.
</p>

<p>
The wording could be simplified and made clear by simply talking about
specifications that permit exceptions to pass, and those that do not, and
simply skip the introduction of a simple set algebra.  However, that would be a
much larger rewrite that should not be undertaken by a mere amateur in the
world of Core drafting, so is left as an exercise for the Core Working Group
itself, should it feel strongly motivated.  It is also the kind of clean-up
that can occur at a more deliberate pace after the initial propsal is adopted.
</p>


<h4>With the removal of dynamic exception specifcations, 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 specifcation 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>Do not touch wording that refers to types in excpetion 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 (and eagle-eyed readers may notice comments in the HTML
source with that discarded drafting).  However, in most or all cases, the
existing text remains valid, but more specialized.  There is still the use case
of an exception specification using a <tt>noexcept</tt> operator, which would
still rely on this wording for expressions within that operator.
</p>
<p>
For refernence (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,3,4            [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,15             [temp.inst]</li>
  <li>14.7.2   p12               [temp.explicit]</li>
  <li>14.8.2   p7                [temp.deduct]</li>
</ul>

<h4><i>exception specification</i> vs. <i>exception-specification</i></h4>
<p>
Sometimes the wording refers to an <i>exception specification</i>,
and at other times it refers to an <i>exception-specification</i>.
This is generally intentional, where the former refers to the notion
of an exception specification, which includes implicit exception
specifications, where the latter refers to explicit use of the grammar
production.
</p>

<h3><a name="6.4">Open Questions</a></h3>

<h4>
Where is the update for Compatibility Annex C?
</h4>
<p>
Oops - remember to include <tt>throw()</tt> specifications might no longer
unwind, but were required to unwind in C++14. 
</p>

<h4>
Is 15.4p5 redundant when combined with exception specifications in the type
system?
</h4>
<p>
It should be possible to greatly simplify this paragraph, if not eliminate it
entirely.
</p>

<h4>
Are there other relevant references that have been missed?
</h4>
<p>
</p>

<h4>
</h4>
<p>
</p>


<h2><a name="7.0">Proposed Wording</a></h2>
<p>
Two attempts are made at drafting new wording.<p>
</p>
<p>
The first stays as close as possible to the original wording, retaining the
idea of sets of types that may pass through an exception specification, but
simplifiying the idea so that only two sets exist in practice: the empty set,
and the set of all types.  The intent is to provide a basis for stable wording
that can be adopted with confidence, at the earliest opportunity.
</p>
<p>
The second attempts to simplify the notion of exception specifications to those
that allow exceptions, and those that do not allow exceptions.  This removes
the notion of set algebra from the standard, and talks much more directly to
the topic of propagating exceptions.  It is more of a rewrite though, and might
be considered riskier as a consequence, even if it would be the preferred long
term approach.
</p>

<h3><a name="7.1">First cut, using current set-based wording</a></h3>
<!--
<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>
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>

<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, <del><i>exception-specification</i>,</del>
<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>
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><sup>31</sup>, 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>


<h4><a name="STD_9.2">9.2 Class members [class.mem]</a></h4>
<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 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>
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 and 8.5.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 <del>or the exception specification
of that constructor</del>.
</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 <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>

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


<h4><a name="STD_14.6.4.1">14.6.4.1 Point of instantiation [temp.point]</a></h4>
<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>


<h4><a name="STD_14.7.1">14.7.1 Implicit instantiation [temp.inst]</a></h4>
<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>


<h4><a name="STD_14.7.2">14.7.2 Explicit instantiation [temp.explicit]</a></h4>
<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>

<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. <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>
-->


<h4><a name="STD_4.12">4.12 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_8.3.5">8.3.5 Functions [dcl.fct]</a></h4>
<p>
8 The return type, the <i>parameter-type-list</i>, the </i>ref-qualifier</i>,
the <i>cv-qualifier-seq</i>, and whether the function has a non-throwing
<i>exception-specification</i>, 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>
<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_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_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.4">15.4 Exception specifications [except.spec]</a></h4>
<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><del>
2 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 “pointer to <i>cv</i> <tt>void</tt>”. A type
<i>cv</i> <tt>T</tt> denoted in a <i>dynamic-exception-specification</i> is
adjusted to type <tt>T</tt>. A type “array of <tt>T</tt>”, or function type
<tt>T</tt> denoted in a <i>dynamic-exception-specification</i> is adjusted to
type “pointer to <tt>T</tt>”. 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>]
</p>

<p><del>
7 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.3).  — <i>end note</i> ]
</del></p>

<p>
8 <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>
9 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>
(9.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>
(9.2) &mdash; otherwise, the function <tt>std::terminate()</tt> is called (15.5.1).
</del></p>
<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>
10 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() <del>throw(X, Y)</del><ins>noexcept</ins>;
     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><del>
11 [ <i>Note:</i> An exception specification is not considered part of a
function’s type; see 8.3.5.  &mdash; <i>end note</i> ]
</del></p>

<p>
12 <del>A</del><ins>The set of</ins> <i>potential exception<ins>s</ins></i> of
a given context is <del>either a type</del><ins>a set of types</ins> that might
be thrown as an exception <del>or a pseudo-type, denoted by &quot;any&quot;,
that represents the situation where an exception of an arbitrary type might be
thrown</del><ins>; the (conceptual) set of all types is used to denote that an
exception of arbitrary type might be thrown</ins>.  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><del>
13 The <i>set of potential exceptions of a function, function pointer, or
member function pointer</i> <tt>f</tt> is defined as follows:
</p></del>
<p><del>
(13.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>
(13.2) &mdash; Otherwise, the set consists of every type in the exception
specification of <tt>f</tt>.
</del></p>

<p>
14 The <i>set of potential exceptions of an expression</i> <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>
(14.1) &mdash; If <tt>e</tt> is a function call (5.2.2):
</p>
<p>
(14.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>
(14.1.2) &mdash; Otherwise, if the <i>postfix-expression</i> has type
&quot;<tt>noexcept</tt> function&quot; or &quot;pointer to <tt>noexcept</tt>
function&quot;, <tt>S</tt> is the empty set.
</p>
<p>
(14.1.3) &mdash; Otherwise, <tt>S</tt> <ins>is the set of all
types</ins><del>contains the pseudo-type &quot;any&quot;</del>.
</p>
<p>
(14.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>
(14.3) &mdash; If <tt>e</tt> initializes an object of type <tt>D</tt> using an
inherited constructor for a class of type <tt>B</tt> (12.6.3), <tt>S</tt> also
contains the sets of potential exceptions of the implied constructor
invocations for subobjects of <tt>D</tt> that are not subobjects of <tt>B</tt>
(including default argument expressions used in such invocations) as selected
by overload resolution, and the sets of potential exceptions of the
initialization of non-static data members from
<i>brace-or-equal-initializers</i> (12.6.2).
</p>
<p>
(14.4) &mdash; if <tt>e</tt> is a <i>throw-expression</i> (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>
(14.5) &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>
(14.6) &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>
(14.7) &mdash; if <tt>e</tt> is a new-expression with a non-constant
<i>expression</i> 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>
(14.<del>8</del><ins>7.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>
(14.<del>9</del><ins>7.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>
(14.<del>10</del><ins>7.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>
(14.<del>11</del><ins>7.4</ins>) &mdash; for <tt>B()</tt>, the set is empty;
</p>
<p>
(14.<del>12</del><ins>7.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>
15 A function with an implied non-throwing exception specification, where the
function’s type is declared to be <tt>T</tt>, is instead considered to be of
type &quot;<tt>noexcept T</tt>&quot;.
</p>
<p>
16 <del>Given an</del><ins>An</ins> implicitly declared special member function
<tt>f</tt> of some class <tt>X</tt></del>, the <i>set of potential exceptions
of the implicitly-declared special member function</i> <tt>f</tt></del> <ins>is
considered to have an implicit exception specification that</ins> 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><del>
17 An implicitly-declared special member function (Clause 12) is 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:
</del></p>
<p><del>
(17.1) &mdash; if <tt>S</tt> contains the pseudo-type &quot;any&quot;, the
implicit exception specification is the set of all types;
</del></p>
<p><del>
(17.2) &mdash; otherwise, the implicit exception specification contains all the
types in <tt>S</tt>.  </p>
</del><p>
<p>
<ins>17</ins>[ <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> ]
</p>
[ <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,
<ins>the exception specification of</ins> <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>


<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.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>

<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>n</ins>
<i><ins>exception</ins><del>noexcept</del>-specification</i> that does not
allow <del>the</del> exception<ins>s</ins> (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.5.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 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.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>n</ins>
<i><ins>exception</ins><del>noexcept</del>-specification</i> that does not
allow <del>the</del> exception<ins>s</ins> (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.5) 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.5.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>


<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 default versions 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>
(2.1) &mdash; <tt>get_new_handler</tt>
</p>
<p><del>
(2.2) &mdash; <tt>get_unexpected</tt>
</del></p>
<p>
(2.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.5.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>
<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>188</sup> except when such a function calls a program-supplied
function that throws an exception.<sup>189</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 an <i>exception-specification</i> may
throw implementation-defined exceptions unless otherwise
specified.<sup>190</sup> <del>An implementation may strengthen this implicit
<i>exception-specification</i> by adding an explicit
one</del>.<sup><del>191</del></sup>
</p>
<p><ins>
5 An implementation may strengthen the exception specification for a non-virtual
function by adding an <i>exception-specification</i> that does not allow
exceptions.
</ins></p>
<p><del>
191) 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>
<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 <i>unspecified</i> 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>


<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 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 <ins>an
<i>exception-specification</i> that does not allow exceptions</ins> <del>a
<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><ins><a name="STD_C.4.x">C.4.x Clause 15: declarations [diff.cpp14.dcl.dcl]</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 were complex and brittle in use.  They interacted badly with the type system,
which would be a more significant issue in C++17 where exception specifications become
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
definition, which has a potentially throwing dyanmic 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>unexcepted</tt> and
might not perform stack unwinding prior to such a call.</ins></p>


<h4><a name="STD_D.2">D.2 Dynamic exception specifications [depr.except.spec]</a></h4>
<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>


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

<h4><a name="STD_D.5.1"><del>D.5.1 Type <tt>unexpected_handler</tt> [unexpected.handler]</del></a></h4>
<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>

<h4><a name="STD_D.5.2"><del>D.5.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.5.3"><del>D.5.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.5.4"><del>D.5.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.5.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>



<h3><a name="7.2">Second cut: simplified wording</h3>

<p>
In addition to the previously proposed edits, make the following changes, and
completely replace clause 15.4 [except.spec] with the text below.
</p>

<p>
Drafting notes:
</p>
<ul>
  <li>Still missing Annex C: missing compatibility clause</li>
</ul>


<h4><a name="STD.2_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
expression allows exceptions (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.2_8.4.2">8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]</a></h4>
<p>
3 If a function that is explicitly defaulted is declared with an
<i>exception-specification</i> that <ins>allows exceptions that are not allowed
by</ins><del>is not compatible (15.4) with</del> the exception specification of
the implicit declaration, 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>


<h4><a name="STD.2_15.4">15.4 Exception specifications [except.spec]</a></h4>
<p><del>
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
that matches a handler of one of the types in the set; 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.
</del></p>
<p>
<pre>
   <del><i>exception-specification:</i></del>
      <del><i>dynamic-exception-specification</i></del>
      <del><i>noexcept-specification</i></del>

   <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><del>
In a <i>noexcept-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>noexcept-specification</i> and does not commence an
initializer (8.5).
</del></p>

<p><del>
2 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 “pointer to <i>cv</i> <tt>void</tt>”. A type
<i>cv</i> <tt>T</tt> denoted in a <i>dynamic-exception-specification</i> is
adjusted to type <tt>T</tt>. A type “array of <tt>T</tt>”, or function type
<tt>T</tt> denoted in a <i>dynamic-exception-specification</i> is adjusted to
type “pointer to <tt>T</tt>”. A <i>dynamic-exception-specification</i> denotes
an exception specification that is the set of adjusted types specified thereby.
</del></p>

<p><del>
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.
</del></p>

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

<p><del>
5 If any declaration of a function has an <i>exception-specification</i> that
is not a <i>noexcept-specification</i> allowing all 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.
</del></p>

<p><del>
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>
</del></p>
<pre>
     <del>struct B {</del>
       <del>virtual void f() throw (int, double);</del>
       <del>virtual void g();</del>
     <del>};</del>

     <del>struct D: B {</del>
       <del>void f();               <i>// ill-formed</i></del>
       <del>void g() throw (int);   <i>// OK</i></del>
     <del>};</del>
</pre>
<p><del>
The declaration of <tt>D::f</tt> is ill-formed because it allows all
exceptions, whereas <tt>B::f</tt> allows only <tt>int</tt> and <tt>double</tt>.
&mdash; <i>end example</i>]
</del></p>

<p><del>
7 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.3).  — <i>end note</i> ]
</del></p>

<p><del>
8 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>.
A function is said to allow all exceptions if its exception specification is
the set of all types.
</del></p>

<p><del>
9 Whenever an exception of type <tt>E</tt> 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 <tt>E</tt>, then
</del></p>
<p><del>
(9.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>
(9.2) &mdash; otherwise, the function <tt>std::terminate()</tt> is called (15.5.1).
</del></p>
<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><del>
10 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>
</del></p>
<pre>
     <del>extern void f() throw(X, Y);</del>
     <del>void g() throw(X) {</del>
       <del>f();     <i>// OK</i></del>
     <del>}</del>
</pre>
<p><del>
the call to <tt>f</tt> is well-formed even though when called, <tt>f</tt> might
throw exception <tt>Y</tt> that <tt>g</tt> does not allow. &mdash; <i>end
example</i> ]
</del></p>

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

<p><del>
12 A <i>potential exception</i> 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>.
</del></p>

<p><del>
13 The <i>set of potential exceptions of a function, function pointer, or
member function pointer</i> <tt>f</tt> is defined as follows:
</del></p>
<p><del>
(13.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>
(13.2) &mdash; Otherwise, the set consists of every type in the exception
specification of <tt>f</tt>.
</del></p>

<p><del>
14 The <i>set of potential exceptions of an expression</i> <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:
</del></p>
<p><del>
(14.1) &mdash; If <tt>e</tt> is a function call (5.2.2):
</del></p>
</p><del>
(14.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).
</del></p>
<p><del>
(14.1.2) &mdash; Otherwise, if the <i>postfix-expression</i> has type
&quot;<tt>noexcept</tt> function&quot; or &quot;pointer to <tt>noexcept</tt>
function&quot;, <tt>S</tt> is the empty set.
</del></p>
<p><del>
(14.1.3) &mdash; Otherwise, <tt>S</tt> contains the pseudo-type &quot;any&quot;.
</del></p>
<p><del>
(14.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.
</del></p>
<p><del>
(14.3) &mdash; If <tt>e</tt> initializes an object of type <tt>D</tt> using an
inherited constructor for a class of type <tt>B</tt> (12.6.3), <tt>S</tt> also
contains the sets of potential exceptions of the implied constructor
invocations for subobjects of <tt>D</tt> that are not subobjects of <tt>B</tt>
(including default argument expressions used in such invocations) as selected
by overload resolution, and the sets of potential exceptions of the
initialization of non-static data members from
<i>brace-or-equal-initializers</i> (12.6.2).
</del></p>
<p><del>
(14.4) &mdash; if <tt>e</tt> is a <i>throw-expression</i> (5.17), <tt>S</tt>
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><del>
(14.5) &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> consists
of the type <tt>std::bad_cast</tt>.
</del></p>
<p><del>
(14.6) &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> consists
of the type <tt>std::bad_typeid</tt>.
</del></p>
<p><del>
(14.7) &mdash; if <tt>e</tt> is a new-expression with a non-constant
<i>expression</i> in the <i>noptr-new-declarator</i> (5.3.4), <tt>S</tt>
consists of the type <tt>std::bad_array_new_length</tt>.
</del></p>
<p><del>
[ <i>Example:</i> Given the following declarations
</del></p>
<pre>
    <del>void f() throw(int);</del>
    <del>void g();</del>
    <del>struct A { A(); };</del>
    <del>struct B { B() noexcept; };</del>
    <del>struct D { D() throw (double); };</del>
</pre>
<p><del>
the set of potential exceptions for some sample expressions is:
</del></p>
<p><del>
(14.8) &mdash; for <tt>f()</tt>, the set consists of <tt>int</tt>;
</del></p>
<p><del>
(14.9) &mdash; for <tt>g()</tt>, the set consists of &quot;any&quot;;
</del></p>
<p><del>
(14.10) &mdash; for <tt>new A</tt>, the set consists of &quot;any&quot;;
</del></p>
<p><del>
(14.11) &mdash; for <tt>B()</tt>, the set is empty;
</del></p>
<p><del>
(14.12) &mdash; for <tt>new D</tt>, the set consists of &quot;any&quot; and
<tt>double</tt>.
</del></p>
<p><del>
&mdash; <i>end example</i> ]
</del></p>

<p><del>
15 A function with an implied non-throwing exception specification, where the
function’s type is declared to be <tt>T</tt>, is instead considered to be of
type &quot;<tt>noexcept T</tt>&quot;.
</del></p>
<p><del>
16 Given an implicitly declared special member function <tt>f</tt> of some
class <tt>X</tt>, the <i>set of potential exceptions of the implicitly-declared
special member function</i> <tt>f</tt> consists of all the members from the
following sets:
</del></p>
<p><del>
(16.1) &mdash; if <tt>f</tt> is a constructor,
</del></p>
<p><del>
(16.1.1) &mdash; the sets of potential exceptions of the constructor invocations
</del></p>
<p><del>
(16.1.1.1) &mdash; for <tt>X</tt>'s non-variant non-static data members,
</del></p>
<p><del>
(16.1.1.2) &mdash; for <tt>X</tt>'s direct base classes, and
</del></p>
<p><del>
(16.1.1.3) &mdash; if <tt>X</tt> is non-abstract (10.4), for <tt>X</tt>'s virtual base classes,
</del></p>
<p><del>
(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>]
</del></p>
<p><del>
(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);
</del></p>
<p><del>
(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);
</del></p>
<p><del>
(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.
</del></p>

<p><del>
17 An implicitly-declared special member function (Clause 12) is 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:
</del></p>
<p><del>
(17.1) &mdash; if <tt>S</tt> contains the pseudo-type &quot;any&quot;, the
implicit exception specification is the set of all types;
</del></p>
<p><del>
(17.2) &mdash; otherwise, the implicit exception specification contains all the
types in <tt>S</tt>.  </p>
</del><p>
<p><del>
[ <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> ]
</del></p>
<p><del>
[ <i>Example:</i>
</del></p>
</p><pre>
   <del>struct A {</del>
     <del>A(int = (A(5), 0)) noexcept;</del>
     <del>A(const A&amp;) throw();</del>
     <del>A(A&amp;&amp;) throw();</del>
     <del>~A() throw(X);</del>
   <del>};</del>
   <del>struct B {</del>
     <del>B() throw();</del>
     <del>B(const B&amp;) = default;  <i>// exception specification contains no types</i></del>
     <del>B(B&amp;&amp;, int = (throw Y(), 0)) noexcept;</del>
     <del>~B() throw(Y);</del>
   <del>};</del>
   <del>int n = 7;</del>
   <del>struct D : public A, public B {</del>
     <del>int * p = new (std::nothrow) int[n];</del>
     <del><i>// exception specification of D::D() contains X and std::bad_array_new_length</i></del>
     <del><i>// exception specification of D::D(const D&amp;) contains no types</i></del>
     <del><i>// exception specification of D::D(D&amp;&amp;) contains Y</i></del>
     <del><i>// exception specification of D::~D() contains X and Y</i></del>
   <del>};</del>
</pre>
<p><del>
Furthermore, if <tt>A::~A()</tt> or <tt>B::~B()</tt> 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> ]
</del></p>

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

<p><del>
19 An <i>exception-specification</i> is considered to be <i>needed</i> when:
<del></p>
<p><del>
(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);
<del></p>
<p><del>
(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;
<del></p>
<p><del>
(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);
<del></p>
<p><del>
(19.4) &mdash; the function is defined; or
<del></p>
<p><del>
(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> ]
<del></p>
<p><del>
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.
<del></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>


<p><ins>
1 The <i>exception specification</i> of a function is a predicate indicating
whether the function might exit via an exception. If the predicate evaluates as
<tt>false</tt>, 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.
</ins></p>
<p>
<pre>
   <ins><i>exception-specification:</i></ins>
      <ins>noexcept ( <i>constant-expression</i> )</ins>
      <ins>noexcept</ins>
      <ins>throw ( )</ins>
</pre>
</p>
<p><ins>
2 In an <i>exception-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>exception-specification</i> and does not commence an
initializer (8.5).  The <i>exception-specification</i> <tt>noexcept</tt>
(without a <i>const-expression</i>) is equivalent to the
<i>exception-specification</i> <tt>noexcept(true)</tt>.  The
<i>exception-specification</i> <tt>throw()</tt> is deprecated (see Annex D),
and equivalent to the <i>exception-specification</i> <tt>noexcept(true)</tt>.
</ins></p>

<p><ins>
3 An <i>exeption specification</i> is said to allow exceptions if the predicate
evaluates to <tt>false</tt>.  Otherwise, it does not allow exceptions.
</ins></p>

<p><ins>
4 If any declaration of a function has an <i>exception specification</i> that
does not allow exceptions, all declarations, including the definition and any
explicit specialization, of that function shall have an <i>exception
specification</i> that does not allow exceptions.  If any declaration of a
pointer to function, reference to function, or pointer to member function has
an <i>exception specification</i> that does not allow exceptions, all
occurrences of that declaration shall have an <i>exception-specification</i>
that does not allow exceptions.  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 allows exceptions only if the <i>exception-specification</i>s
of all other declarations of that function allow exceptions. A diagnostic is
required only if the <i>exception-specification</i>s are not compatible within
a single translation unit.
</ins></p>

<p><ins>
5 If a virtual function has an exception specification that does not allow
exceptions, all declarations, including the definition, of any function that
overrides that virtual function in any derived class shall not allow
exceptions, unless the overriding function is defined as deleted. [
<i>Example:</i>
</ins></p>
<pre>
     <ins>struct B {</ins>
       <ins>virtual void f() noexcept;</ins>
       <ins>virtual void g();</ins>
       <ins>virtual void h() noexcept;</ins>
     <ins>};</ins>

     <ins>struct D: B {</ins>
       <ins>void f();              <i>// ill-formed</i></ins>
       <ins>void g() noexept;      <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 allows all
exceptions, whereas <tt>B::f</tt> allows no exceptions. &mdash; <i>end
example</i>]
</ins></p>

<p><ins>
6 Whenever an exception 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 exceptions, the function <tt>std::terminate()</tt> is
called (15.5.1).
</ins></p>

<p><ins>
7 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>
</ins></p>
<pre>
     <ins>extern void f() noexcept;</ins>
     <ins>void g() {</ins>
       <ins>f();  <i>// OK</i></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 that <tt>g</tt> does not allow. &mdash; <i>end
example</i> ]
</ins></p>

<p><ins>
8 An expression allows an exception if and only if any of its immediate
subexpressions allows an exception.  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>.
</ins></p>

<p><ins>
9 If <tt>e</tt> initializes an object of type <tt>D</tt> using an inherited
constructor for a class of type <tt>B</tt> (12.6.3), the set of immediate
subexpressions of <tt>e</tt> includes the implied constructor invocations for
subobjects of <tt>D</tt> that are not subobjects of <tt>B</tt> (including
default argument expressions used in such invocations) as selected by overload
resolution, and the initialization of non-static data members from
<i>brace-or-equal-initializers</i> (12.6.2).
</ins></p>

<p><ins>
10 An expression (or subexpression) <tt>e</tt> does not allow exceptions unless
</ins></p>
<p><ins>
(10.1) <tt>e</tt> invokes a function, or member function, whose <i>exception
specification</i> allows exceptions, or
</ins></p>
<p><ins>
(10.2) <tt>e</tt> implicitly invokes a function (such as an overloaded
<tt>operator</tt>, 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 allows exceptions, or
</ins></p>
<p><ins>
(10.3) <tt>e</tt> is a <i>throw-expression</i> (5.17), or
</ins></p>
<p><ins>
(10.4) <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></p>
<p><ins>
(10.5) <tt>e</tt> is a <tt>typeid</tt> expression applied to a glvalue
expression whose type is a polymorphic class type (5.2.8), or
</ins></p>
<p><ins>
(10.6) <tt>e</tt> is a new-expression with a non-constant
<i>expression</i> in the <i>noptr-new-declarator</i> (5.3.4), or
</ins></p>
<p><ins>
(10.7) any of the immediate subexpressions of <tt>e</tt> allows exceptions.
</ins></p>

<p><ins>
11 An implicitly declared special member function that is a constructor for a
class <tt>X</tt> has an exception specification that does not allow exceptions
unless any of the constructors selected by overload resolution in the implicit
definition of that constructor to initialize direct base classes and non-static
members, and, unless <tt>X</tt> is abstract, to initialize virtual base
classes, has an exception specification that allows exceptions, or the
invocation of such initialization contains an expression that allows
exceptions, such as default argument expressions used in such invocations, or
<i>brace-or-equal-initializer</i>s for non-static data members.
</ins></p>

<p><ins>
12 [ <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>]
</ins></p>

<p><ins>
13 [ <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> ]
</ins></p>
<p><ins>
[ <i>Example:</i>
</ins></p>
<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>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 (std::nothrow) int[n];</ins>
     <ins><i>// D::D() allows exceptions, as the new operator may throw bad_array_new_length</i></ins>
     <ins><i>// D::D(const D&amp;) does not allow exceptions</i></ins>
     <ins><i>// D::D(D&amp;&amp;) allows exceptions, as the default argument for B's constructor may throw</i></ins>
     <ins><i>// D::~D() allows exceptions</i></ins>
   <ins>};</ins>
</pre>
<p><ins>
Furthermore, if <tt>A::~A()</tt> were virtual, the exception specification of
<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> ]
</ins></p>


<p><ins>
14 An implicitly declared special member function that is the destructor for a
class <tt>X</tt> has an exception specification that does not allow exceptions
unless any of the destructors for its direct or virtual base classes and
non-variant non-static data members has a destructor with an exception
specification that allows exceptions.
</ins></p>

<p><ins>
15 An implicitly declared special member function <tt>f</tt> that is an
assignment operator for a class <tt>X</tt> has an exception specification that
does not allow exceptions unless the implicit definition of <tt>f</tt>
selects by overload resolution an assignment operator from a direct base
class, or from a non-variant non-static data members, that allows exceptions.
</ins></p>

<p><ins>
16 A function with an implied non-throwing exception specification, where the
function’s type is declared to be <tt>T</tt>, is instead considered to be of
type &quot;<tt>noexcept T</tt>&quot;.
</ins></p>

<p><ins>
17 A deallocation function (3.7.4.2) with no explicit
<i>exception-specification</i> has an exception specification that does not
allow exceptions.
</ins></p>

<p>
18 An <i>exception-specification</i> is considered to be <i>needed</i> when:
</p>
<p>
(18.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>
(18.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>
(18.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>
(18.4) &mdash; the function is defined; or
</p>
<p>
(18.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>



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