<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Rvalue References and Exception Safety</title>
<style type="text/css">
p {text-align:justify}
li {text-align:justify}
ins {background-color:#A0FFA0}
del {background-color:#FFA0A0}

div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

</style>
</head>

<body>
<h1>Rvalue References and Exception Safety</h1>

<p>Authors: Douglas Gregor, David Abrahams<br>
Contact: doug.gregor@gmail.com, dave@boostpro.com<br>
Organization: Apple, BoostPro Computing<br>
Date: 2009-03-23<br>
Number: N2855=09-0045</p>

<h3>Table of Contents</h3>
<ul>
  <li><a href="#intro">Introduction</a>
    <ul>
      <li><a href="#ereview">Review of Exception Safety Guarantees in the Library</a></li>
      <li><a href="#mreview">Review of Move Semantics Idioms</a></li>
    </ul>
  </li>
  <li><a href="#problem">The Problem</a>
    <ul>
      <li><a href="#throwing-move-constructor">The Problem With Throwing Move Constructors</a></li>
      <li><a href="#strong-except-model">A Model of Strong Exception Safety</a></li>
      <li><a href="#throwing-pair">Throwing Move Constructors in the Standard Library</a></li>
    </ul>
  </li>
  <li><a href="#solution">Proposed Solution</a>
    <ul>
      <li><a href="#noexcept">The <code>noexcept</code> Specifier</a></li>
      <li><a href="#noexcept-concepts"><code>noexcept</code> In Concepts</a></li>
      <li><a href="#nothrowmove">Move Constructors are Non-Throwing</a></li>
      <li><a href="#noexcept-destruct">Destructors are Non-throwing</a></li>
      <li><a href="#noexcept-block">The <code>noexcept</code> Block</a></li>
      <li><a href="#exception-spec">Deprecate Exception Specifications</a></li>
      <li><a href="#library">Library Changes</a>
        <ul>
          <li><a href="#concepts">Nothrow Moving and Copying Concepts</a></li>
          <li><a href="#aggregate">Move Constructors and Move Assignment Operators</a></li>
          <li><a href="#noexcept-annot"><code>noexcept</code> annotations</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="#syntax">Alternative Syntax</a></li>
</ul>

<h2 id="intro">Introduction</h2>

<p>This paper describes a problem with the move construction idiom
that compromises the exception safety guarantees made by the Standard
Library. In particular, well-formed C++03 programs, when compiled with
the C++0x Standard Library, can no longer rely on the strong exception
safety guarantee provided by certain standard library container
operations. This change silently breaks existing user code.  In this
paper, we characterize the problem itself and outline a solution that
extends the language and modifies the library.</p>

<h3 id="ereview">Review of Exception Safety Guarantees in the
Library</h3>

<p>Within the library, we characterize the behavior of a function with
respect to exceptions based on the guarantees that the implementation
must provide if an exception is thrown. These guarantees describe the
state of the program once a thrown exception has unwound the stack
past the point of that function. We recognize three levels of exception
safety guarantees for a given library function:

<dl>
  <dt>Basic exception guarantee</dt>
  <dd>The invariants of the component are preserved, and no resources are leaked.</dd>

  <dt>Strong exception guarantee</dt>
  <dd>The operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.</dd>

  <dt>No-throw guarantee</dt>
  <dd>The operation will not throw an exception.</dd>
</dl>

<p>The Standard Library provides at least the basic exception
guarantee throughout, which has not changed with the introduction of
rvalue references. However, some functions of the library provide the
strong exception guarantee, such as <code>push_back</code>
(23.1.1p10).</p>

<h3 id="mreview">Review of Move Semantics Idioms</h3>

The most common "move constructor" signature for a type <code>T</code>
is <code>T(T&&)</code>, but <em>every</em> move constructor:
<ol>
  <li>Can be called with a single non-const rvalue argument of type <code>T</code></li>
  <li>Has a non-const reference parameter to which that rvalue is bound
  <li>Transfers resources from that rvalue into the newly-constructed object
    </ol>
Although move construction modifies its argument by transferring
resources away from it, move construction from a real rvalue is still
a "logically non-mutating" operation.  Since the move constructor
holds the only reference to that rvalue, any modifications are
invisible to the rest of the program.  These invisible move
constructions can take effect automatically whenever an rvalue may
need to be copied, for example when an rvalue argument is passed by
value.

However, move construction can also be <em>explicitly requested</em>
for lvalue arguments.  The standard idiom
is <code>T(std::move(x))</code>, where <code>x</code> is an lvalue of
type <code>T</code>.  The <code>std::move</code> function template
simply casts its lvalue argument to the corresponding rvalue type:

<pre>
template &lt;class T&gt;
T&& move(T& x) { return static_cast&lt;T&&&gt;(x); }
</pre>
  
The <code>T(std::move(x))</code> idiom is only a move <em>request</em>
because in general, <code>T</code> may not have a move constructor, in
which case an available copy constructor will be used instead.  Such
an explicit move request can be used anytime a function knows that a
particular value is no longer needed.  The simplest example is
in <code>std::swap</code>:

<pre>
template &lt;class T&gt;
void swap(T& x, T& y)
{
   T tmp(std::move(x));  // 1
   x = std::move(y);     // 2
   y = std::move(tmp);   // 3
}
</pre>

In this case, it is safe to move from <code>x</code> in line 1 because
we are about to assign into <code>x</code> in line 2.
Since <em>copying</em> <code>x</code> is also an acceptable (though
sometimes suboptimal) way to transfer its value into <code>tmp</code>,
this code still works when <code>T</code> has a copy constructor but
no move constructor.  

The act of constructing a new <code>T</code> from an
explicitly-generated <code>T&&</code> bound to an lvalue is known in
this paper as "the move operation," whether it actually ends up moving
or falls back to invoking a copy constructor.

<h2 id="problem">The Problem</h2>

<p>The problem addressed by this paper is three-fold.  First, under
C++0x, some existing types such
as <code>pair&lt;string,legacy_type&gt;</code> automatically acquire a
throwing move constructor.  Second, currently-legal operations such as
insertion into a container of those pairs will invoke undefined
behavior, because the C++0x Standard Library bans throwing move
constructors in those operations.  Third, operations such
as <code>vector<T>::push_back</code>, that are currently required to
provide the strong exception guarantee, only provide the basic
guarantee when <code>T</code>'s move constructor can throw.

<h3 id="throwing-move-constructor">The Problem With Throwing Move Constructors</h3>

<p>As an example,
we consider <code>vector</code>'s <code>push_back</code> operation,
e.g.,</p>

<pre>
vec.push_back(x);
</pre>

<p>In the call to <code>push_back</code>, if the size of the
<code>vector</code> is the same as its capacity, we will have to
allocate more storage for the <code>vector</code>. In this case, we
first allocate more storage and then "move" the contents from the old
storage into the new storage. Finally, we copy the new element into
the new storage and, if everything has succeeded, free the old
storage. The reallocation routine looks something like this:</p>

<pre>
T* reallocate(T *old_ptr, size_t old_capacity) {
  // #1: allocate new storage
  T* new_ptr = (T*)new char[sizeof(T) * old_capacity * 2];

  // #2: try to move the elements to the new storage
  unsigned i = 0;
  try {
    // #2a: construct each element in the new storage from the corresponding
    // element in the old storage, treating the old elements as rvalues
    for (; i &lt; old_capacity; ++i)
      new (new_ptr + i) T(std::move(old_ptr[i])); // "move" operation
  } catch (...) {
    // #2b: destroy the copies and deallocate the new storage
    for (unsigned v = 0; v &lt; i; ++v)
      new_ptr[v]-&gt;~T();
    delete[]((char*)new_ptr);
    throw;
  }

  // #3: free the old storage
  for (i = 0; i &lt; old_capacity; ++i)
    old_ptr[i]-&gt;~T();
  delete[]((char*)old_ptr);
  return new_ptr;
}
</pre>

<p>For this discussion we are interested in section #2, which handles
the movement of values from the old storage to the new storage. The
use of <code>std::move</code> treats the elements in the old storage
as rvalues, enabling a move constructor (if available) or falling back
to a copy constructor (if no move constructor is available) with the
same syntax.</p>

<p>Consider reallocation of the vector when the type stored in the
vector provides only a copy constructor (and no move constructor), as
shown below. Here, we copy elements from the old storage (top) to the
new storage (bottom).</p>

<table border="0">
  <tr>
    <td>
      <table border="1">
        <tr>
          <td>a</td><td>b</td><td>c</td><td>d</td>
          <td>e</td><td>f</td><td>g</td><td>h</td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td>
      <table border="0">
        <tr>
          <td>&darr;</td><td>&darr;</td><td>&darr;</td><td>&darr;</td>
          <td>&darr;</td><td></td><td></td><td></td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td>
      <table border="1">
        <tr>
          <td>a</td><td>b</td><td>c</td><td>d</td>
          <td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<p>While copying the fifth element (<code>e</code>) the copy constructor throws an exception. At this point, we can still recover, since the old storage still contains the original (unmodified) data. Thus, the recovery code (section #2b) destroys the elements in the new storage and then frees the new storage, providing the strong exception safety guarantee.</p>

<p>When the type stored in the vector provides a move constructor, each of the values is moved from the old storage into the new storage, potentially mutating the values in the old storage. The notion is shown below, half-way through the reallocation:</p>

<table border="0">
  <tr>
    <td>
      <table border="1">
        <tr>
          <td>?</td><td>?</td><td>?</td><td>?</td>
          <td>e</td><td>f</td><td>g</td><td>h</td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td>
      <table border="0">
        <tr>
          <td>&dArr;</td><td>&dArr;</td><td>&dArr;</td><td>&dArr;</td>
          <td>&dArr;</td><td></td><td></td><td></td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td>
      <table border="1">
        <tr>
          <td>a</td><td>b</td><td>c</td><td>d</td>
          <td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<p>When the element's move constructor cannot throw, the
initialization of the new storage is guaranteed to succeed, since no
operations after the initial memory allocation can throw.</p>

<p>However, if the element's move constructor can throw an exception,
that exception can occur after the vector's state has been altered
(say, while moving the value <code>e</code>), and there's no reliable
way to recover the vector's original state, since any attempt to move
the previously-moved elements back into the vector's storage could
also throw.  Hence, the best we can do is maintain the basic
guarantee, where no resources are leaked but the first four elements in
the vector have indeterminate values.</p>

<h3 id="strong-except-model">A Model of Strong Exception Safety</h3>

<p>Stepping back from this specific instance, we can formulate a
simple model for achieving the strong exception-safety guarantee. In
this model, we take the set of operations that we need to perform in
our routine and partition them into two sets: those operations that
perform nonreversible modifications to existing data and those
operations that can throw exceptions. Providing strong exception
safety means placing any operations that can throw exceptions (memory
allocation, copying, etc.) before any operations that perform
nonreversible modifications to existing data
(destroying an object, freeing memory).</p>

<p>Reconsidering <code>vector</code> reallocation in terms of this
model, we see that, if we ignore throwing move constructors, the
implementation of <code>reallocate</code> performs all of its
possibly-throwing routines up front: we allocate memory, then copy
(which may throw) or move (which won't throw), then we complete the
operation. Either way, at some point within the routine we have
committed to only using operations that can no longer throw, such as
deallocating memory or destroying already-constructed objects.</p>

<p>The problem with a throwing move constructor is that it fits into
both partitions. It can throw exceptions (obviously) and it is also a
non-reversible modification, because (1) moving is permitted to
transfer resources and (2) there is no non-throwing operation to
reverse the transfer of resources.</p>

<p>Based on this model, prohibiting the use of types that have
throwing move constructors <em>appears</em> to solve the problem. It
does help, but we'll need to go further than that to prevent the
generation of throwing move constructors in standard library class
templates.</p>

<!-- One immediate problem with this approach (which is -->
<!-- already used by vector's <code>push_back</code> specification, among -->
<!-- other things) is that it places the burden of ensuring that all move -->
<!-- constructors are non-throwing on the user, without providing the user -->
<!-- with any tools to determine whether this requirement is actually -->
<!-- met. -->

<h3 id="throwing-pair">Throwing Move Constructors in the Standard Library</h3>

<p>So, how easy is it to violate the requirement that move
constructors not throw exceptions? It turns out to be effortless.  In
fact existing, well-formed C++03 programs will violate this
requirement when compiled with the C++0x Standard Library because the
standard library itself creates throwing move constructors. As an
example, consider a simple <code>Matrix</code> type that stores its
values on the heap:</p>

<pre>
class Matrix {
  double *data;
  unsigned rows, cols;

public:
  Matrix(const Matrix&amp; other) : rows(other.rows), cols(other.cols) {
    data = new double [rows * cols];
    // copy data...
  }
};
</pre>

<p>The <code>Matrix</code> type has a copy constructor that can throw an exception, but it has no move constructors. A <code>vector</code> of <code>Matrix</code> values is certainly well-formed and its <code>push_back</code> provides the strong exception safety guarantee. This is true both in C++03 and in C++0x.</p>

<p>Next, we compose a <code>std::string</code> with a <code>Matrix</code> using <code>std::pair</code>:</p>

<pre>
typedef std::pair&lt;std::string, Matrix&gt; NamedMatrix;
</pre>

<p>Consider <code>std::pair</code>'s move constructor, which will look something like this (simplified!):</p>

<pre>
template&lt;typename T, typename U&gt;
struct pair {
  pair(pair&amp;&amp; other)
    : first(std::move(other.first)), second(std::move(other.second)) { }

  T first;
  U second;
};
</pre>

<p>Here, the <code>pair</code>'s <code>first</code> data member is
a <code>std::string</code>, which has a non-throwing move constructor
that modifies its source
value. The <code>pair</code>'s <code>second</code> data member is
a <code>Matrix</code>, which has a throwing copy constructor but no
move constructor. When we compose these two types, we end up with a
type&mdash;<code>std::pair&lt;std::string, Matrix&gt;</code>&mdash;that merges
their behaviors. This <code>pair</code>'s move constructor performs a
non-reversible modification on the <code>first</code> member of the
pair (moving the resources of the <code>std::string</code>) and then
performs a potentially-throwing copy construction on
the <code>second</code> member of the pair (copying
the <code>Matrix</code>). Thus, we have composed two well-behaved
types, one from the library and one from user code, into a type that
violates the prohibition on throwing move constructors. Moreover, this
problem affects valid C++03 code, which will silently invoke undefined
behavior when compiled with a C++0x Standard Library </p>

<h2 id="solution">Proposed Solution</h2>

<p>Given the prohibition on throwing move
constructors, <code>pair</code> should only declare a move constructor
when it is guaranteed that the underlying move operations for the
types it aggregates are both non-throwing.  Using concept syntax, one
might imagine that such a constructor would be written as:</p>

<pre>
  requires NothrowMoveConstructible&lt;T&gt; &amp;&amp; NothrowMoveConstructible&lt;U&gt;
    pair(pair&amp;&mp; other)
      : first(std::move(other.first)), second(std::move(other.second)) { }
</pre>

<p>In this case, <code>pair</code> will only provide a move
constructor when that move constructor is guaranteed to be
non-throwing. Therefore, <code>std::pair&lt;std::string,
Matrix&gt;</code> will not provide a move constructor, and reallocating
a <code>vector</code> of these pairs will use the copy constructor,
maintaining the strong exception safety
guarantee. Naturally, <code>pair</code> is not the only type whose
move constructor is affected: any standard library and user type that
aggregates other values, including tuples and containers, will need
similarly-constrained move constructors.</p>

<p>At present, there is no satisfactory way to write
the <code>NothrowMoveConstructible</code> concept. Using C++0x as
currently specified, we could try to write the new concept as
follows:</p>

<pre>
concept NothrowMoveConstructible&lt;typename T, typename U = T&gt; {
  requires RvalueOf&lt;U&gt; &amp;&amp; Constructible&lt;T, RvalueOf&lt;U&gt;::type&gt;;
}
</pre>

<p>The important aspect of this concept is that it is not an
<code>auto</code> concept, so clients are required to "opt in" by
explicitly stating, via a concept map, that they provide a
non-throwing move constructor. The library would provide concept maps
for its own types, e.g.</p>

<pre>
concept_map NothrowMoveConstructible&lt;string&gt; { }
</pre>

<p>Some of these concept maps will, naturally, be conditional on their
inputs. For example, <code>pair</code>'s concept map can be expressed
as follows:</p>

<pre>
template&lt;typename T1, typename T2, typename U, typename V>
  requires NothrowMoveConstructible&lt;T1, U&gt; &amp;&amp; NothrowMoveConstructible&lt;T2, V&gt;
  concept_map NothrowMoveConstructible&lt;pair&lt;T1, T2&gt;, pair&lt;U, V&gt;&gt; { }
</pre>

<p>If diligently applied throughout the library and user code,
<code>NothrowMoveConstructible</code> permits the safe use of
move semantics within the library, retaining the strong exception
safety guarantee.</p>

<p>The danger with a library-only solution is that it is far too easy
for users of the language to accidentally write a move constructor
that can throw exceptions (see <code>std::pair</code>), and a single
class or class template that makes such a mistake compromises the
exception safety guarantees of the library. The concepts system cannot
protect the user from such a mistake, because there is no way to
statically determine whether a function can throw exceptions. Even if
concepts could prevent such an error in the library, non-templated and
unconstrained templates would still be susceptible to this class of
errors. To address these problems, we propose to introduce language
facilities that allow the non-throwing guarantee to be declared for
functions, statically enforced by the compiler, and queried by
concepts.</p>

<h3 id="noexcept">The <code>noexcept</code> Specifier</h3>

<p>We propose the addition of a new declaration specifier,
<code>noexcept</code>, that indicates that the function it applies to
does not throw any exceptions. The <code>noexcept</code> specifier can
only be applied to function declarators, e.g.,</p>

<pre>
noexcept int printf(const char* format, ...); // okay: printf does not throw exceptions.
noexcept int (*funcptr)(const char*, ...); // okay: pointer to a function that does not throw exceptions
noexcept int x; // error: not a function declarator
</pre>

<p>The <code>noexcept</code> specifier differs from an empty exception
specification (spelled <code>throw()</code>) in two important
ways. First, a <code>noexcept</code> function is ill-formed if it (or
any function it calls) may throw an exception, e.g.,</p>

<pre>
noexcept int foo(int);
int bar(int);
noexcept void wibble(int x, int y) {
  x = foo(x); // okay: foo can not throw any exceptions
  y = bar(y); // error: bar() could throw an exception

  try {
    y = bar(y); 
  } catch (...) {
    y = 0;
  } // okay: all exceptions that could be thrown have been captured
}
</pre>

<p>Second, the presence or absence of the <code>noexcept</code>
specifier is part of a function type. Thus, the types of the function
pointers <code>fp1</code> and <code>fp2</code>, shown below, are
distinct:</p>

<pre>
noexcept int (*fp1)(int); // okay: pointer to a function that does not throw exceptions
int (*fp2)(int); // okay: pointer to a function that may throw exceptions
</pre>

<p>There is an implicit conversion from pointers and references
to <code>noexcept</code> pointers to their potentially-throwing
equivalents. For example:</p>

<pre>
noexcept int f(int);
int g(int);

noexcept int (*fp1)(int) = &amp;f; // okay: exact match
int (*fp2)(int) = &amp;g; // okay: exact match
int (*fp3)(int) = &amp;f; // okay: conversion from pointer to <code>noexcept</code> function to a pointer to a non-<code>noexcept</code> function
noexcept int (*fp4)(int) = &amp;g; // error: no conversion from a pointer to a throwing function type to a pointer to a non-throwing function type
</pre>

<p>In short, <code>noexcept</code> provides the behavior that
many users expect from <code>throw()</code>. That exception specifications
are not statically checked is a <a
 href="http://www.gotw.ca/publications/mill22.htm">constant source of
confusion</a>, especially for programmers who have used the similar
(statically-checked) facilities in Java. Moreover, exception
specifications have a poorly-defined role in the C++ type system,
because they can only be used in very limited ways.</p>

<p><strong>Note:</strong> functions cannot be overloaded based on <code>noexcept</code>
alone, and <code>noexcept</code> is not part of a function's
signature. For example, the following code is ill-formed:</p>

<pre>
noexcept void f() { } // #1
void f() { } // #2: redefinition of #1
</pre>

<h3 id="noexcept-concepts"><code>noexcept</code> In Concepts</h3>

<p>The <code>noexcept</code> specifier can be used on associated
functions within concepts, allowing one to detect whether a particular
operation is guaranteed not to throw exceptions. For example:</p>

<pre>
auto concept NothrowMoveConstructible&lt;typename T, typename U = T&gt; {
  requires RvalueOf&lt;U&gt;;
  noexcept T::T(RvalueOf&lt;U&gt;::type);
}
</pre>

<p>This new, <code>noexcept</code> formulation of the
<code>NothrowMoveConstructible</code> concept has two benefits over
the previous formulation. First, since the <code>noexcept</code>
property is statically checked, there is no potential for users to
accidentally claim that no exceptions will be thrown from their move
constructors. Second, since we have strong static checking for the
no-throw policy, we have made this an <code>auto</code> concept, so
that users need not write concept maps for this low-level
concept.</p>

<h3 id="nothrowmove">Move Constructors are Non-Throwing</h3>
<p>Types with throwing move constructors are prohibited within the standard library, and we have not seen motivating use cases for such a feature. On the other hand, failure to mark a non-throwing move constructor as <code>noexcept</code> means that users will miss out on the many optimization opportunities in the standard library that depend on rvalue references.</p>

<p>We therefore propose that all move constructors be implicitly <code>noexcept</code>. This way, users that implement move constructors can be certain that their move constructors (1) will be used by the standard library and (2) will meet the non-throwing requirements of the standard library.</p>

<p>Specifically, for a class <code>X</code>, any constructor whose first parameter is of type <code>X&amp;&amp;</code> and whose remaining parameters, if any, all have default arguments, is considered a move constructor. For a class tempate <code>X</code>, any constructor or constructor template whose first parameter is of type <code>X&lt;T1, T2, ..., TN&gt;</code> for any <code>T1</code>, <code>T2</code>, ..., <code>TN</code> and whose remaining parameters, if any, all have default arguments, is considered a move constructor or move constructor template. If a constructor or constructor template is a move constructor or move constructor template, it is implicitly declared as <code>noexcept</code>.</p>

<!-- Drafting note: The move constructor generated for closure types will need to be fixed, too. -->

<h3 id="noexcept-destruct">Destructors are Non-throwing</h3>

<p>Nearly every operation that involves construction of an object also involves destruction of that object. Therefore, the vast majority of uses of a non-throwing move constructor will also require a non-throwing destructor. Non-throwing destructors are not new; in fact, the C++ Standard Library requires that destructors not throw exceptions, and it is very rare that destructors ever throw. For these reasons, we propose that all destructors be implicitly be declared <code>noexcept</code> and are, therefore, banned from throwing exceptions.</p>

<p>Unlike with move constructors, there are some use cases for destructors that throw exceptions. One such example is a return value that can't be ignored, e.g.,</pre>

<pre>
class ImportantReturn {
  int value;
  bool eaten;

public:
  ImportantReturn(int v) : value(v), eaten(false) { }

  ~ImportantReturn() {
    if (!eaten) throw important_return_value_ignored(value);
  }

  operator int() const {
    eaten = true;
    return value;
  }
};
</pre>

<p>For these destructors (which are a very slim minority) we require a syntax to disable the implicit <code>noexcept</code>. We propose to use the syntax <code>throw(...)</code> to mean "this function can throw any exception." This syntax is already a <a href="http://msdn.microsoft.com/en-us/library/wfa0edys.aspx">Microsoft extension</a>, and fits in well with existing syntax.</p>

<p>Note that implicitly making destructors <code>noexcept</code> will break existing code for classes like <code>ImportantReturn</code>. Users will need to add the <code>throw(...)</code> specification on these destructors to return them to their C++03 behavior. Given that few destructors need to throw exceptions---and that such classes cannot be used with the C++03 or C++0x standard libraries---we expect that the impact of this breaking change will be small.</p>

<h3 id="noexcept-block">The <code>noexcept</code> Block</h3>

<p>Statically checking that the body of a function does not throw any exceptions can reject as ill-formed certain programs that are careful to avoid throwing exceptions. As a simple example, imagine a function <code>sqrt(double x)</code> that computes the square root of <code>x</code>. If given zero or a negative number, it will throw an <code>std::out_of_range</code> exception. Now, imagine a function that uses <code>sqrt()</code>:</p>

<pre>
double sqrt(double); // may throw exceptions

noexcept void f(double &x) {
  if (x &gt; 0) {
    x = sqrt(x); // ill-formed: sqrt(x) might throw an exception!
  }
}
</pre>

<p>This code is ill-formed, because the call to may throw exceptions. The user has properly guarded the call to <code>sqrt</code> by checking its preconditions within <code>f</code>, but the compiler is unable to intepret the program to prove that <code>f</code> will not throw. To address this problem, we propose the addition of a <code>noexcept</code> block, which will be used as follows:</p>

<pre>
double sqrt(double); // may throw exceptions

noexcept void f(double &x) {
  if (x &gt; 0) {
    noexcept { x = sqrt(x); } // okay: if sqrt(x) throws, invokes undefined behavior
  }
}
</pre>

<p>The <code>noexcept</code> block states that no exceptions will be thrown by the code within its compound statement. An exception that escapes from a <code>noexcept</code> block results in undefined behavior.</p>

<h3 id="exception-spec">Deprecate Exception Specifications</h3>

<p>Exception specifications have not proven to be as useful as we had hoped. Their lack of static checking has limited their usability and confused users, and they provide few benefits for compilers. Moreover, exception specifications aren't useful in generic code, where functions need to know whether an exception can be thrown or not but don't know (or care) what kind of exceptions can be thrown. For these and other reasons, exception specifications are discouraged [<a href="http://www.boost.org/development/requirements.html#Exception-specification">1</a>, <a href="http://www.gotw.ca/publications/mill22.htm">2</a>, <a href="http://www.linuxprogrammingblog.com/cpp-exception-specifications-are-evil">3</a>].</p>

<p>In fact, the <code>noexcept</code> specifier---along with the ability to detect whether an operation is <code>noexcept</code> via concepts---provides precisely the statically-checked exception specifications that are required in C++ code. We therefore propose to deprecate C++ exception specifications in C++0x: the community has already decided to avoid exception specifications and <code>noexcept</code> provides a superior alternative.</p>


<h3 id="library">Library Changes</h3>
<p>The introduction of <code>noexcept</code> and its use throughout the standard library will require significant changes in a few areas. The changes are summarized below.</p>

<h4 id="concepts">Nothrow Moving and Copying Concepts</h4>
<p>We propose the introduction of new concepts for non-throwing assignment and construction:</p>

<pre>
<ins>auto concept NothrowConstructible&lt;typename T, typename... Args&gt;
<ins>  : Constructible&lt;T, Args...&gt; {</ins>
<ins>  noexcept T::T(Args...);</ins>
<ins>}</ins>

<ins>auto concept NothrowMoveConstructible&lt;typename T&gt; : MoveConstructible&lt;T&gt; {</ins>
<ins>  requires RvalueOf&lt;T&gt;</ins>
<ins>        &amp;&amp; NothrowConstructible&lt;T, RvalueOf&lt;T&gt;::type&gt;;</ins>
<ins>}</ins>

<ins>auto concept HasNothrowAssign&lt;typename T, typename U&gt; : HasAssign&lt;T, U&gt; {</ins>
<ins>  noexcept result_type T::operator=(U);</ins>
<ins>}</ins>

<ins>auto concept NothrowMoveAssignable&lt;typename T&gt; : MoveAssignable&lt;T&gt;, HasNothrowAssign&lt;T, T&amp;&amp;&gt; { }</ins>
</pre>

<p>In addition, we need <code>Nothrow</code> variants of the concepts used for scoped allocators:</p>

<pre>
<ins>concept NothrowConstructibleWithAllocator&lt;class T, class Alloc, class... Args&gt; {</ins>
<ins>  noexcept T::T(allocator_arg_t, Alloc, Args&amp;&amp;...);</ins>
<ins>}</ins>

<ins>auto concept NothrowAllocatableElement&lt;class Alloc, class T, class... <ins>Args&gt; : AllocatableElement&lt;Alloc, T, Args...&gt; {</ins>
<ins>  noexcept void Alloc::construct(T*, Args&amp;&amp;...);</ins>
<ins>}</ins>
</pre>

<p>Finally, we improve the existing <code>NothrowDestructible</code> concept to statically check the no-throw requirements:</p>

<pre>
auto concept NothrowDestructible&lt;typename T&gt; : HasDestructor&lt;T&gt; {
  <ins>noexcept T::~T();</ins>
}
</pre>

<h4 id="aggregate">Move Constructors and Move Assignment Operators</h4>

<p>Throughout the library, each class template that aggregates other templates and has a move constructor will need to have its move constructor and move assignment operator be specified as <code>noexcept</code> and only be provided when the operations they use are known to be <code>noexcept</code>. We summarize the changes here, but have omitted the changes for some library components pending a full review of the library.<p>

<h5>20.3.3 Pairs [pairs]</h5>

<p>Two of <code>pair</code>'s move constructors will be modified as follows:</p>
<pre>
template&lt;class U, class V&gt; 
  requires <ins>Nothrow</ins>Constructible&lt;T1, RvalueOf&lt;U&gt;::type&gt; &amp;&amp; <ins>Nothrow</ins>Constructible&lt;T2, RvalueOf&lt;V&gt;::type&gt; 
  <ins>noexcept</ins> pair(pair&lt;U, V&gt;&amp;&amp; p);

template&lt;class U, class V, Allocator Alloc&gt;
  requires <ins>Nothrow</ins>ConstructibleWithAllocator&lt;T1, Alloc, RvalueOf&lt;U&gt;::type&gt; 
        &amp;&amp; <ins>Nothrow</ins>ConstructibleWithAllocator&lt;T2, Alloc, RvalueOf&lt;V&gt;::type&gt; 
  <ins>noexcept</ins> pair(allocator_arg_t, const Alloc& a, pair&lt;U, V&gt;&amp;&amp; p);
</pre>

<p>Similarly, <code>pair</code>'s move assignment operator will be modified as follows:</p>
<pre>
template&lt;class U , class V&gt; 
  requires Has<ins>Nothrow</ins>Assign&lt;T1, RvalueOf&lt;U&gt;::type&gt; &amp;&amp; Has<ins>Nothrow</ins>Assign&lt;T2, RvalueOf&lt;V&gt;::type&gt; 
  <ins>noexcept</ins> pair&amp; operator=(pair&lt;U , V&gt;&amp;&amp; p); 
</pre>

<h5>20.5.2 Class template tuple [tuple.tuple]</h5>

<p>Two of <code>tuple</code>'s move constructors will be modified as follows:</p>

<pre>
template &lt;class... UTypes&gt; 
  requires <ins>Nothrow</ins>Constructible&lt;Types, RvalueOf&lt;UTypes&gt;::type&gt;... 
  <ins>noexcept</ins> tuple(tuple&lt;UTypes...&gt;&amp;&amp;);

template &lt;Allocator Alloc, class... UTypes&gt; 
  requires <ins>Nothrow</ins>ConstructibleWithAllocator&lt;Types, Alloc, RvalueOf&lt;UTypes&gt;::type&gt;... 
  <ins>noexcept</ins> tuple(allocator_arg_t, const Alloc&amp; a, tuple&lt;UTypes...&gt;&amp;&amp;);
</pre>

<p><code>tuple</code>'s move assignment operator will be modified as follows:</p>

<pre>
template &lt;class... UTypes&gt; 
  requires Has<ins>Nothrow</ins>Assign&lt;Types, RvalueOf&lt;UTypes&gt;::type&gt;... 
  <ins>noexcept</ins> tuple&amp; operator=(tuple&lt;UTypes...&gt;&amp;&amp;); 
</pre>

<h5>23.3.2 Class template deque [deque]</h5>
<p>Modify two of <code>deque</code>'s constructors as follows:</p>

<pre>
requires <ins>Nothrow</ins>AllocatableElement&lt;Alloc, T, T&amp;&amp;&gt; <ins>&amp;&amp; NothrowMoveConstructible&lt;Alloc&gt;</ins>
   <ins>noexcept</ins> deque(deque&amp;&amp;);
requires <ins>Nothrow</ins>AllocatableElement&lt;Alloc, T, T&amp;&amp;&gt; <ins>&amp;&amp; NothrowConstructible&lt;Alloc, const Alloc&amp;&gt;</ins>
   <ins>noexcept</ins> deque(deque&amp;&amp;, const Alloc&amp;);
</pre>

<p>Modify the <code>deque</code> move assignment operator as follows:</p>

<pre>
requires <ins>Nothrow</ins>AllocatableElement&lt;Alloc, T, T&amp;&amp;&gt; &amp;&amp; MoveAssignable&lt;T&gt;
      <ins>&amp;&amp; NothrowMoveAssignable&lt;Alloc&gt;</ins>
  <ins>noexcept</ins> deque&lt;T,Alloc&gt;&amp; operator=(deque&lt;T,Alloc&gt;&amp;&amp; x);
</pre>

<p>Each of the other standard containers and container adaptors will require similar modifications.</p>

<h4 id="noexcept-annot"><code>noexcept</code> Annotations</h4>

<p>Since a <code>noexcept</code> function can only call into other <code>noexcept</code> functions, much of the standard library itself will require <code>noexcept</code> annotations to make those parts of the library usable. Therefore, for any function that is currently specified as <code>throw()</code> we propose to replace the <code>throw()</code> with a <code>noexcept</code> specifier. Additionally, for any operation with a clause</p>

<ul>
  <li><i>Throws</i>: nothing</li>
</ul>

<p>we propose to remove this clause and instead introduce the <code>noexcept</code> specifier on the corresponding declaration.</p>

<p>These changes are likely to effect a significant portion of the Standard Library, including nearly all of the C standard library. In most cases, the changes merely enforce requirements that have already been present in the library.</p>

<h2 id="syntax">Alternative Syntax</h2>

<p>We have considered several alternative syntaxes for <code>noexcept</code>, and we catalog the most promising alternatives here:</p>

<dl>
  
<dt>The <code>nothrow</code> keyword</dt>
<dd>
  <b>Why it works</b>: <code>nothrow</code> would be our first choice for a keyword to describe a non-throwing function (or block). This term has been in use colloquially to describe non-throwing functions and is also used within the standard library. If the technical problems (described below) can be overcome, we would prefer to use <code>nothrow</code> rather than <code>noexcept</code>.<br>
  <b>Why it doesn't</b>: the standard library also has an object named <code>nothrow</code>, which is declared as:
  <pre>
extern const nothrow_t nothrow;
</pre>
  If <code>nothrow</code> were to become a keyword, this object could no longer be defined in the standard library and would have to be removed. We then would have to provide some special syntax allowing existing uses of this object to still work. For example:
  <pre>
using std::nothrow;
X* ptr = new (nothrow) X;
X* ptr2 = new (std::nothrow) X;
</pre>
</dd>
    
<dt>A <code>nothrow</code> attribute</dt>
<dd>
  <b>Why it works</b>: both functions and statements can be annotated with attributes, and since attributes do not require a keyword we can use the "<code>nothrow</code>" identifier. In addition, <code>nothrow</code> is an attribute already supported by the GNU compiler with a similar meaning.<br>
  <b>Why it doesn't</b>: attributes aren't meant to affect the type system, but it is crucial for the "non-throwing" property to be a part of a function's type. Plus, the existing <code>GNU</code> attribute, whose semantics don't exactly match the intended behavior of <code>noexcept</code>, may prove a hindrance.
</dd>
<br>
<dt>Variants of throw specifications (<code>!throw</code>, <code>throw(void)</code>, <code>throw(not)</code>)</dt>
<dd>
  <b>Why it works</b>: we have already carved out a syntactic space for describing the exception behavior of functions, so it doesn't require major surgery to extend that syntax.<br>
  <b>Why it doesn't</b>: <code>noexcept</code> behaves very differently from existing exception specifications, so having too many syntactic similarities confuses the semantics of the two features in a way that is likely to cause problems for programmers.
</dl>

<hr>
<address></address>
<!-- hhmts start --> Last modified: Mon Mar 23 09:12:03 PDT 2009 <!-- hhmts end -->
</body> </html>
