Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57480 - sandbox/committee/rvalue_ref
From: dgregor_at_[hidden]
Date: 2009-11-08 01:24:11


Author: dgregor
Date: 2009-11-08 01:24:10 EST (Sun, 08 Nov 2009)
New Revision: 57480
URL: http://svn.boost.org/trac/boost/changeset/57480

Log:
Update noexcept paper
Text files modified:
   sandbox/committee/rvalue_ref/N2983-throwing-move.rst | 51 ++++++++++++++++++++++++++------------
   sandbox/committee/rvalue_ref/N2983.html | 53 +++++++++++++++++++++++++++------------
   2 files changed, 72 insertions(+), 32 deletions(-)

Modified: sandbox/committee/rvalue_ref/N2983-throwing-move.rst
==============================================================================
--- sandbox/committee/rvalue_ref/N2983-throwing-move.rst (original)
+++ sandbox/committee/rvalue_ref/N2983-throwing-move.rst 2009-11-08 01:24:10 EST (Sun, 08 Nov 2009)
@@ -167,7 +167,7 @@
 current working draft; it would be identical to the proposed
 ``is_nothrow_constructible<T,T&&>`` from N2953_. In other words, it
 returns ``true`` only when it can prove the move constructor doesn't
-throw, and is *allowed* to return ``false`` otherwise, even if the
+throw, and returns ``false`` otherwise, even if the
 move constructor is actually nonthrowing.
 
 An Optimization Hint
@@ -187,7 +187,7 @@
 any operation decorated with ``noexcept(true)``. Class maintainers could
 label their move constructors ``noexcept(true)`` to indicate non-throwing
 behavior, and the library is permitted to take advantage of that
-labelling if it can be detected (via “compiler magic”).
+labeling if it can be detected (via “compiler magic”).
 
 Note that the usefulness of ``noexcept(true)`` as an optimization hint
 goes way beyond the narrow case introduced by N2855_. In fact, it
@@ -218,6 +218,11 @@
 exception specification above is entirely optional; its presence or
 absence doesn't affect the correctness of a move constructor.
 
+Since the common case for ``noexcept`` is to label certain operations
+as never throwing exceptions (without the need for a condition), the
+exception-specification ``noexcept`` is provided as a shorthand for
+``noexcept(true)``.
+
 operator ``noexcept(``\ *expression*\ ``)``
 *******************************************
 
@@ -226,8 +231,25 @@
 *bool-constant-expr*\ ``)`` available to make the information
 available, it makes sense to generalize the traits into an operator
 similar to ``sizeof`` and ``typeof`` that can give us answers about
-*any* expression.
+*any* expression. The new operator ``noexcept(``\ *expression*\ ``)``
+determines whether the given *expression* can throw.
 
+The ``noexcept`` operator is conservative, and will only evaluate true
+when the compiler can be certain that the expression will not throw,
+because no subexpression can throw and there are no calls to any
+functions that allow exceptions. Note that the wording in this
+document does *not* give compilers freedom to perform any additional
+analysis to determine whether a function can throw. For example,
+``noexcept(f())`` will evaluate ``false`` given the following function
+``f``, even though a sufficiently smart compiler could determine that
+``f`` does not throw::
+
+ float get_float();
+ void f() {
+ float x = get_float();
+ if (sqrt(fabs(x)) < 0)
+ throw x;
+ }
 
 Interactions with Other Proposals
 *********************************
@@ -237,12 +259,10 @@
 Crowl in N2953_, is harmonious with our proposal. For example, since
 throwing move constructors are allowed, default move constructors will
 be generated in more cases, with performance benefits if *any*
-subobjects have been move-enabled.
-
-As a matter of QOI, a default move constructor would probably gain an
-exception specification whose boolean constant parameter is computed
-from the results of has_nothrow_move on all subobjects, but, being a
-matter of QOI, that doesn't have any effect on standard text.
+subobjects have been move-enabled. A default move constructor should
+gain a ``noexcept`` specification whose boolean constant parameter is
+computed from the results of the ``noexcept`` operator for the move of
+all subobjects.
 
 The proposed ``[[nothrow]]`` attribute is just a less-powerful version
 of this feature. In particular, it can't express the hint shown for
@@ -261,8 +281,8 @@
 in the standard. Standardizing ``noexcept(true)`` gives everyone access
 to this optimization tool.
 
-Implicit ``noexcept(true)`` for Destructors
-*******************************************
+Implicit ``noexcept`` for Destructors
+*************************************
 
 So few destructors can throw exceptions that the default
 exception-specification for destructors could be changed from nothing
@@ -272,8 +292,6 @@
 reasonably easily migrated. However, we don't think this change would
 be appropriate for C++0x at this late date, so we're not proposing it.
 
-FIXME: Add some discussion about implementation freedom with noexcept(true).
-
 Proposed Changes to Standard Wording
 ************************************
 
@@ -416,19 +434,20 @@
       *type-id-list*, *type-id* :raw-html:`<code>...</code><sub><i>opt</i></sub>`
 
     :raw-html:`<span class="ins"><em>noexcept-specification:</em></span>`
- :raw-html:`<span class="ins"><code>noexcept (</code> <em>constant-expression<span class="sub">opt</span></em> <code>)</code></span>`
+ :raw-html:`<span class="ins"><code>noexcept (</code> <em>constant-expression</em> <code>)</code></span>`
+ :raw-html:`<span class="ins"><code>noexcept</code></span>`
 
   :raw-html:`<span class="ins">In a <i>noexcept-specification</i>, the
   <i>constant-expression</i>, if supplied, shall be a constant expression
   ([expr.const]) that is contextually converted to <code>bool</code>
   ([conv] Clause 4). A <i>noexcept-specification</i>
- <code>noexcept()</code> is equivalent to <code>noexcept(true)</code>.</span>`
+ <code>noexcept</code> is equivalent to <code>noexcept(true)</code>.</span>`
 
   7 A function is said to *allow* an exception of type ``E`` if its :raw-html:`<i><span class="ins">dynamic-</span>exception-specification</i>` contains a type ``T`` for which a handler of type ``T`` would be a match (15.3) for an exception of type ``E``.
 
   .. comment :raw-html:`<span class="ins">, if its <i>noexcept-specification</i> is <code>noexcept(false)</code>, or if the function has no <i>exception-specification</i>`.
 
- 11 A function with no *exception-specification* :raw-html:`<span class="ins">, or with an <i>exception-specification</i> of the form <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>false</code>,</span>` allows all exceptions. :raw-html:`<span class="ins">An <i>exception-specification</i> is <i>non-throwing</i> if it is of the form <code>throw()</code>, <code>noexcept()</code>, or <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>true</code>.</span>` A function with :del:`an empty` :ins:`a non-throwing` *exception-specification* :raw-html:`<span class="del">, <code>throw()</code>,</span>` does not allow any exceptions.
+ 11 A function with no *exception-specification* :raw-html:`<span class="ins">, or with an <i>exception-specification</i> of the form <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>false</code>,</span>` allows all exceptions. :raw-html:`<span class="ins">An <i>exception-specification</i> is <i>non-throwing</i> if it is of the form <code>throw()</code>, <code>noexcept</code>, or <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>true</code>.</span>` A function with :del:`an empty` :ins:`a non-throwing` *exception-specification* :raw-html:`<span class="del">, <code>throw()</code>,</span>` does not allow any exceptions.
 
   14 In :raw-html:`a<span class="del">n</span> <i><span class="ins">dynamic-</span>exception-specification</i>,` a *type-id* followed by an ellipsis is a pack expansion (14.6.3).
 

Modified: sandbox/committee/rvalue_ref/N2983.html
==============================================================================
--- sandbox/committee/rvalue_ref/N2983.html (original)
+++ sandbox/committee/rvalue_ref/N2983.html 2009-11-08 01:24:10 EST (Sun, 08 Nov 2009)
@@ -3,7 +3,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
+<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
 <title>Allowing Move Constructors to Throw</title>
 <meta name="author" content="David Abrahams, Rani Sharoni, Doug Gregor" />
 <meta name="organization" content="BoostPro Computing" />
@@ -341,7 +341,7 @@
 <li><a class="reference internal" href="#operator-noexcept-expression" id="id11">operator <tt class="docutils literal"><span class="pre">noexcept(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt></a></li>
 <li><a class="reference internal" href="#interactions-with-other-proposals" id="id12">Interactions with Other Proposals</a></li>
 <li><a class="reference internal" href="#existing-practice" id="id13">Existing Practice</a></li>
-<li><a class="reference internal" href="#implicit-noexcept-true-for-destructors" id="id14">Implicit <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> for Destructors</a></li>
+<li><a class="reference internal" href="#implicit-noexcept-for-destructors" id="id14">Implicit <tt class="docutils literal"><span class="pre">noexcept</span></tt> for Destructors</a></li>
 <li><a class="reference internal" href="#proposed-changes-to-standard-wording" id="id15">Proposed Changes to Standard Wording</a><ul>
 <li><a class="reference internal" href="#keywords-lex-key" id="id16">2.12 Keywords [lex.key]</a></li>
 <li><a class="reference internal" href="#allocation-functions-basic-stc-dynamic-allocation" id="id17">3.7.4.1 Allocation functions [basic.stc.dynamic.allocation]</a></li>
@@ -497,7 +497,7 @@
 current working draft; it would be identical to the proposed
 <tt class="docutils literal"><span class="pre">is_nothrow_constructible&lt;T,T&amp;&amp;&gt;</span></tt> from <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2953.html">N2953</a>. In other words, it
 returns <tt class="docutils literal"><span class="pre">true</span></tt> only when it can prove the move constructor doesn't
-throw, and is <em>allowed</em> to return <tt class="docutils literal"><span class="pre">false</span></tt> otherwise, even if the
+throw, and returns <tt class="docutils literal"><span class="pre">false</span></tt> otherwise, even if the
 move constructor is actually nonthrowing.</p>
 </div>
 <div class="section" id="an-optimization-hint">
@@ -514,7 +514,7 @@
 any operation decorated with <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt>. Class maintainers could
 label their move constructors <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> to indicate non-throwing
 behavior, and the library is permitted to take advantage of that
-labelling if it can be detected (via “compiler magic”).</p>
+labeling if it can be detected (via “compiler magic”).</p>
 <p>Note that the usefulness of <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> as an optimization hint
 goes way beyond the narrow case introduced by <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855</a>. In fact, it
 goes beyond move construction: when the compiler can detect
@@ -540,6 +540,10 @@
 be <em>required</em> if there is a ban on throwing move constructors, the
 exception specification above is entirely optional; its presence or
 absence doesn't affect the correctness of a move constructor.</p>
+<p>Since the common case for <tt class="docutils literal"><span class="pre">noexcept</span></tt> is to label certain operations
+as never throwing exceptions (without the need for a condition), the
+exception-specification <tt class="docutils literal"><span class="pre">noexcept</span></tt> is provided as a shorthand for
+<tt class="docutils literal"><span class="pre">noexcept(true)</span></tt>.</p>
 </div>
 <div class="section" id="operator-noexcept-expression">
 <h1><a class="toc-backref" href="#id11">operator <tt class="docutils literal"><span class="pre">noexcept(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt></a></h1>
@@ -547,7 +551,25 @@
 not just in this proposal). Once we have <tt class="docutils literal"><span class="pre">noexcept(</span></tt><em>bool-constant-expr</em><tt class="docutils literal"><span class="pre">)</span></tt> available to make the information
 available, it makes sense to generalize the traits into an operator
 similar to <tt class="docutils literal"><span class="pre">sizeof</span></tt> and <tt class="docutils literal"><span class="pre">typeof</span></tt> that can give us answers about
-<em>any</em> expression.</p>
+<em>any</em> expression. The new operator <tt class="docutils literal"><span class="pre">noexcept(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt>
+determines whether the given <em>expression</em> can throw.</p>
+<p>The <tt class="docutils literal"><span class="pre">noexcept</span></tt> operator is conservative, and will only evaluate true
+when the compiler can be certain that the expression will not throw,
+because no subexpression can throw and there are no calls to any
+functions that allow exceptions. Note that the wording in this
+document does <em>not</em> give compilers freedom to perform any additional
+analysis to determine whether a function can throw. For example,
+<tt class="docutils literal"><span class="pre">noexcept(f())</span></tt> will evaluate <tt class="docutils literal"><span class="pre">false</span></tt> given the following function
+<tt class="docutils literal"><span class="pre">f</span></tt>, even though a sufficiently smart compiler could determine that
+<tt class="docutils literal"><span class="pre">f</span></tt> does not throw:</p>
+<pre class="literal-block">
+float get_float();
+void f() {
+ float x = get_float();
+ if (sqrt(fabs(x)) &lt; 0)
+ throw x;
+}
+</pre>
 </div>
 <div class="section" id="interactions-with-other-proposals">
 <h1><a class="toc-backref" href="#id12">Interactions with Other Proposals</a></h1>
@@ -556,11 +578,10 @@
 Crowl in <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2953.html">N2953</a>, is harmonious with our proposal. For example, since
 throwing move constructors are allowed, default move constructors will
 be generated in more cases, with performance benefits if <em>any</em>
-subobjects have been move-enabled.</p>
-<p>As a matter of QOI, a default move constructor would probably gain an
-exception specification whose boolean constant parameter is computed
-from the results of has_nothrow_move on all subobjects, but, being a
-matter of QOI, that doesn't have any effect on standard text.</p>
+subobjects have been move-enabled. A default move constructor should
+gain a <tt class="docutils literal"><span class="pre">noexcept</span></tt> specification whose boolean constant parameter is
+computed from the results of the <tt class="docutils literal"><span class="pre">noexcept</span></tt> operator for the move of
+all subobjects.</p>
 <p>The proposed <tt class="docutils literal"><span class="pre">[[nothrow]]</span></tt> attribute is just a less-powerful version
 of this feature. In particular, it can't express the hint shown for
 <tt class="docutils literal"><span class="pre">pair</span></tt>'s move constructor above. We suggest it be dropped.</p>
@@ -577,8 +598,8 @@
 in the standard. Standardizing <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> gives everyone access
 to this optimization tool.</p>
 </div>
-<div class="section" id="implicit-noexcept-true-for-destructors">
-<h1><a class="toc-backref" href="#id14">Implicit <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> for Destructors</a></h1>
+<div class="section" id="implicit-noexcept-for-destructors">
+<h1><a class="toc-backref" href="#id14">Implicit <tt class="docutils literal"><span class="pre">noexcept</span></tt> for Destructors</a></h1>
 <p>So few destructors can throw exceptions that the default
 exception-specification for destructors could be changed from nothing
 (i.e. <tt class="docutils literal"><span class="pre">noexcept(false)</span></tt>) to <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> with only a tiny
@@ -586,7 +607,6 @@
 where used properly, ought to be a well-known “caution area” that is
 reasonably easily migrated. However, we don't think this change would
 be appropriate for C++0x at this late date, so we're not proposing it.</p>
-<p>FIXME: Add some discussion about implementation freedom with noexcept(true).</p>
 </div>
 <div class="section" id="proposed-changes-to-standard-wording">
 <h1><a class="toc-backref" href="#id15">Proposed Changes to Standard Wording</a></h1>
@@ -702,16 +722,17 @@
   <em>type-id-list</em>, <em>type-id</em> <span class="raw-html"><code>...</code><sub><i>opt</i></sub></span>
 
 <span class="raw-html"><span class="ins"><em>noexcept-specification:</em></span></span>
- <span class="raw-html"><span class="ins"><code>noexcept (</code> <em>constant-expression<span class="sub">opt</span></em> <code>)</code></span></span>
+ <span class="raw-html"><span class="ins"><code>noexcept (</code> <em>constant-expression</em> <code>)</code></span></span>
+ <span class="raw-html"><span class="ins"><code>noexcept</code></span></span>
 </pre>
 <p><span class="raw-html"><span class="ins">In a <i>noexcept-specification</i>, the
 <i>constant-expression</i>, if supplied, shall be a constant expression
 ([expr.const]) that is contextually converted to <code>bool</code>
 ([conv] Clause 4). A <i>noexcept-specification</i>
-<code>noexcept()</code> is equivalent to <code>noexcept(true)</code>.</span></span></p>
+<code>noexcept</code> is equivalent to <code>noexcept(true)</code>.</span></span></p>
 <p>7 A function is said to <em>allow</em> an exception of type <tt class="docutils literal"><span class="pre">E</span></tt> if its <span class="raw-html"><i><span class="ins">dynamic-</span>exception-specification</i></span> contains a type <tt class="docutils literal"><span class="pre">T</span></tt> for which a handler of type <tt class="docutils literal"><span class="pre">T</span></tt> would be a match (15.3) for an exception of type <tt class="docutils literal"><span class="pre">E</span></tt>.</p>
 <!-- comment :raw-html:`<span class="ins">, if its <i>noexcept-specification</i> is <code>noexcept(false)</code>, or if the function has no <i>exception-specification</i>`. -->
-<p>11 A function with no <em>exception-specification</em> <span class="raw-html"><span class="ins">, or with an <i>exception-specification</i> of the form <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>false</code>,</span></span> allows all exceptions. <span class="raw-html"><span class="ins">An <i>exception-specification</i> is <i>non-throwing</i> if it is of the form <code>throw()</code>, <code>noexcept()</code>, or <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>true</code>.</span></span> A function with <span class="del">an empty</span> <span class="ins">a non-throwing</span> <em>exception-specification</em> <span class="raw-html"><span class="del">, <code>throw()</code>,</span></span> does not allow any exceptions.</p>
+<p>11 A function with no <em>exception-specification</em> <span class="raw-html"><span class="ins">, or with an <i>exception-specification</i> of the form <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>false</code>,</span></span> allows all exceptions. <span class="raw-html"><span class="ins">An <i>exception-specification</i> is <i>non-throwing</i> if it is of the form <code>throw()</code>, <code>noexcept</code>, or <code>noexcept(<i>constant-expression</i>)</code> where the <i>constant-expression</i> yields <code>true</code>.</span></span> A function with <span class="del">an empty</span> <span class="ins">a non-throwing</span> <em>exception-specification</em> <span class="raw-html"><span class="del">, <code>throw()</code>,</span></span> does not allow any exceptions.</p>
 <p>14 In <span class="raw-html">a<span class="del">n</span> <i><span class="ins">dynamic-</span>exception-specification</i>,</span> a <em>type-id</em> followed by an ellipsis is a pack expansion (14.6.3).</p>
 </blockquote>
 <p>Add the following new paragraph:</p>


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