<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2236: kill_dependency unconditionally noexcept</title>
<meta property="og:title" content="Issue 2236: kill_dependency unconditionally noexcept">
<meta property="og:description" content="C++ library issue. Status: SG1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2236.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#SG1">SG1</a> status.</em></p>
<h3 id="2236"><a href="lwg-active.html#2236">2236</a>. <code>kill_dependency</code> unconditionally noexcept</h3>
<p><b>Section:</b> 32.5.2 <a href="https://wg21.link/atomics.syn">[atomics.syn]</a>, 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a> <b>Status:</b> <a href="lwg-active.html#SG1">SG1</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2013-01-19 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#atomics.syn">active issues</a> in [atomics.syn].</p>
<p><b>View all other</b> <a href="lwg-index.html#atomics.syn">issues</a> in [atomics.syn].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#SG1">SG1</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The "magic" <code>kill_dependency</code> function is a function without any constraints on the template parameter <code>T</code> 
and is specified as
</p>

<blockquote><pre>
template &lt;class T&gt;
T kill_dependency(T y) noexcept;
</pre><blockquote>
<p>
-14- <i>Effects</i>: The argument does not carry a dependency to the return value (1.10).
<p/>
-15- <i>Returns</i>: <code>y</code>.
</p>
</blockquote></blockquote>

<p>
I wonder whether the unconditional <code>noexcept</code> is really intended here:
Assume we have some type <code>U</code> that has a potentially throwing move
constructor (or it has a potentially throwing copy constructor and no
move constructor), for any "normal" function template with the same
signature and the same effects (modulo the dependency magic) this
would mean that it cannot safely be declared <code>noexcept</code> because of the
return statement being part of the complete function call affected by
<code>noexcept</code> (The by-value function argument is irrelevant in this
context). In other words it seems that a function call such as
</p>

<blockquote><pre>
struct S {
  ...
  S(const S&amp; r) { if(<em>some condition</em>) throw Something(); }
  ...
};

int main() {
  S s1 = ...;
  S s2 = std::kill_dependency(s1);
}
</pre></blockquote>

<p>
would be required to call <code>std::terminate</code> if the copy constructor of <code>S</code> throws during the return 
of <code>std::kill_dependency</code>.
<p/>
To require copy elision for this already magic function would look like a low-hanging fruit to solve this problem, 
but this case is not covered by current copy elision rules see 12.8 p31 b1:
<p/>
"&mdash; in a return statement in a function with a class return type, when the expression is the name of a non-volatile 
automatic object (other than a function or catch-clause parameter) with the same <em>cv</em>-unqualified type as the 
function return type, the copy/move operation can be omitted by constructing the automatic object directly into the
function's return value".
<p/>
Some options come into my mind:
</p>
<ol>
<li><p>
Make the exception-specification a constrained one in regard via <code>std::is_nothrow_move_constructible</code>:
</p>

<blockquote><pre>
template &lt;class T&gt;
T kill_dependency(T y) noexcept(<em>see below</em>);
</pre></blockquote>

<p>
This is similar to the approach taken for function templates such as <code>std::swap</code>.
</p>
</li>

<li><p>
Use perfect forwarding (This needs further wording to correct the effects):
</p>

<blockquote><pre>
template &lt;class T&gt;
T&amp;&amp; kill_dependency(T&amp;&amp; y) noexcept;
</pre></blockquote>
</li>

<li><p>
Impose constraints on the template arguments in regard to throwing exceptions while copying/moving.
</p></li>

<li><p>
Keep the state as it is but possibly add a note about a call of <code>std::terminate</code> in above scenario.
</p></li>
</ol>

<p>
A second problem is that the current wording is not clear whether it is well-defined to call the function with
types that are reference types, such as in the following example:
</p>

<blockquote><pre>
#include &lt;atomic&gt;

int main()
{
  int a = 12;
  int&amp; b = std::kill_dependency&lt;int&amp;&gt;(a);
}
</pre></blockquote>

<p>
It is unclear what kind of dependency is killed here. This is presumably a core language problem, but could
affect the possible resolutions of the problem.
</p>

<p><i>[2014-11 Urbana]</i></p>

<p>
Recommend using a revised example:
</p>
<blockquote><pre>
int lookup(class D* p) 
{
  class E* q = p-&gt;a.load(memory_order_consume);
  int y = std::kill_dependency(q-&gt;y);
}
</pre></blockquote>

<p><i>[2015-02 Cologne]</i></p>

<p>
Handed over to SG1.
</p>



<p id="res-2236"><b>Proposed resolution:</b></p>





</body>
</html>
