Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51937 - sandbox/committee/rvalue_ref
From: dave_at_[hidden]
Date: 2009-03-23 11:59:54


Author: dave
Date: 2009-03-23 11:59:52 EDT (Mon, 23 Mar 2009)
New Revision: 51937
URL: http://svn.boost.org/trac/boost/changeset/51937

Log:
Mostly editorial fixes

Text files modified:
   sandbox/committee/rvalue_ref/rvalue-ref-exception-safety.html | 64 +++++++++++++++++++++------------------
   1 files changed, 34 insertions(+), 30 deletions(-)

Modified: sandbox/committee/rvalue_ref/rvalue-ref-exception-safety.html
==============================================================================
--- sandbox/committee/rvalue_ref/rvalue-ref-exception-safety.html (original)
+++ sandbox/committee/rvalue_ref/rvalue-ref-exception-safety.html 2009-03-23 11:59:52 EDT (Mon, 23 Mar 2009)
@@ -200,9 +200,7 @@
 <pre>
 T* reallocate(T *old_ptr, size_t old_capacity) {
   // #1: allocate new storage
- T* new_ptr = (T*)malloc(sizeof(T) * old_capacity * 2);
- if (new_ptr == NULL)
- throw std::bad_alloc();
+ T* new_ptr = (T*)new char[sizeof(T) * old_capacity * 2];
 
   // #2: try to move the elements to the new storage
   unsigned i = 0;
@@ -215,14 +213,14 @@
     // #2b: destroy the copies and deallocate the new storage
     for (unsigned v = 0; v &lt; i; ++v)
       new_ptr[v]-&gt;~T();
- free(new_ptr);
+ delete[]((char*)new_ptr);
     throw;
   }
 
   // #3: free the old storage
   for (i = 0; i &lt; old_capacity; ++i)
     old_ptr[i]-&gt;~T();
- free(old_ptr);
+ delete[]((char*)old_ptr);
   return new_ptr;
 }
 </pre>
@@ -355,8 +353,10 @@
 reverse the transfer of resources.</p>
 
 <p>Based on this model, prohibiting the use of types that have
-throwing move constructors appears to solve the problem, and it does
-help somewhat.</p>
+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 -->
@@ -429,13 +429,10 @@
 
 <h2 id="solution">Proposed Solution</h2>
 
-<p>The problematic throwing move constructor in our example comes from
-the aggregation of two well-formed types, so we focus our attention on
-the <code>pair</code> move constructor. In particular, given the
-prohibition on move constructors that may throw
-exceptions, <code>pair</code> should only declare a move constructor
+<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
+types it aggregates are both non-throwing. Using concept syntax, one
 might imagine that such a constructor would be written as:</p>
 
 <pre>
@@ -447,7 +444,7 @@
 <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
+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
@@ -455,7 +452,10 @@
 aggregates other values, including tuples and containers, will need
 similarly-constrained move constructors.</p>
 
-<p>At present, there is no good way to write the <code>NothrowMoveConstructible</code> concept. One option that exists within the current language is to write the new concept as follows:</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; {
@@ -490,16 +490,17 @@
 
 <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, 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>
+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>
 
@@ -544,7 +545,9 @@
 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>
+<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);
@@ -556,8 +559,8 @@
 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 many ways, <code>noexcept</code> provides the behavior that
-users expect from <code>throw()</code>. That exception specifications
+<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
@@ -565,8 +568,9 @@
 specifications have a poorly-defined role in the C++ type system,
 because they can only be used in very limited ways.</p>
 
-<p>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>
+<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


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk