Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>(Quoting the C++03 standard)</p> <p>First there's §12.2/3:</p> <blockquote> <p>When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). <strong>Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.</strong> This is true even if that evaluation ends in throwing an exception.</p> </blockquote> <p>I believe this is a red herring, because of §1.9/13:</p> <blockquote> <p>[Note: certain contexts in C++ cause the evaluation of a full-expression that results from a syntactic construct other than expression (5.18). For example, in 8.5 one syntax for initializer is</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;<code>( expression-list )</code></p> <p>but the resulting construct is a function call upon a constructor function with expression-list as an argument list; such a function call is a full-expression. For example, in 8.5, another syntax for initializer is</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;<code>= initializer-clause</code></p> <p>but again <strong>the resulting construct might be a function call upon a constructor function with one assignment-expression as an argument; again, the function call is a full-expression</strong>. ]</p> </blockquote> <p>This implies to me that <code>A(b).yield()</code> is itself a full expression, rendering §12.2/3 irrelevant here.</p> <p>Then we get into sequence points -- §1.9/7:</p> <blockquote> <p>Accessing an object designated by a volatile lvalue (3.10), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression might produce side effects. <strong>At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.</strong></p> </blockquote> <p>§1.9/16:</p> <blockquote> <p><strong>There is a sequence point at the completion of evaluation of each full-expression.</strong></p> </blockquote> <p>and §1.9/17:</p> <blockquote> <p>When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body. <strong>There is also a sequence point after the copying of a returned value and before the execution of any expressions outside the function.</strong></p> </blockquote> <p>Putting it all together, <em>I think</em> Clang is right and GCC (and MSVC 2010 SP1) is wrong -- the temporary that holds the result of the expression (whose lifetime is being extended as per §12.2/4) is the <code>bool</code> returned from <code>A::yield()</code>, not the temporary <code>A</code> on which <code>yield</code> is invoked. Taking into account §1.9, there should be a sequence point after the call to <code>A::yield()</code> during which the temporary <code>A</code> is destroyed.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload