
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta charset="utf-8">
<title>C++ Coroutine TS Issues</title>
<style type="text/css">
  p {text-align:justify}
  li {text-align:justify}
  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 {border-collapse: collapse;}
  table, th, td {
    border: 1px solid black;
    border-collapse: collapse;
  } 
</style>
</head>
<body>
<h1>C++ Coroutine TS Issues</h1>
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">P0664R2</td>
</tr>
<tr>
<td align="left">Revises</td>
<td align="left">P0664R1</td>
</tr>
<tr>
<td align="left">Date:</td>
<td align="left">Revised 2018-03-08 at 14:25:00 UTC
</td>
</tr>
<tr>
<td align="left">Project:</td>
<td align="left">Programming Language C++</td>
</tr>
<tr>
<td align="left">Reference:</td>
<td align="left">ISO/IEC TS 22277, C++ Extensions for Coroutines</td>
</tr>
<tr>
<td align="left">Audience:</td>
<td align="left">EWG, CWG, LEWG</td>
</tr>
<tr>
<td align="left">Reply to:</td>
<td align="left">Gor Nishanov &lt;<a href="mailto:gorn@microsoft.com">gorn@microsoft.com</a>&gt;</td>
</tr>
</table>
<h2> Introduction </h2>
<p>All proposed resolutions wording is relative to <a href="https://wg21.link/N3736">N4736</a>.</p>
<p>Previous issue list is <a href="wg21.link/P0664R1">P0664R1</a>.</p>
<h2> Table of content </h2>

<ul>
  <li>
    Evolution issues:
      <a href="#24">24</a>
      <a href="#25">25</a>
      <a href="#26">26</a>
      <a href="#27">27</a>
  </li>
  <li>
      CWG issues:
        <a href="#28">28</a>
    </li>
    <li>
      LEWG/LWG issues: <a href="#29">29</a>
    </li>
  </ul>
<!--
<h2> Table of content </h2>

<ul>
  <li>
    <b>[CWG Approved Toronto-7/12/2017]</b> Coroutine issues reviewed and approved by CWG: <a href="#2">2</a> <a href="#6">6</a> <a href="#7">7</a> <a href="#18">18</a> <a href="#21">21</a>
  </li>
  <li>
    <b>[LWG Approved Toronto-7/11/2017]</b> Coroutine issues reviewed and approved by LWG: <a href="#9">9</a> <a href="#10">10</a> <a href="#11">11</a> <a href="#14">14</a> <a href="#15">15</a> <a href="#22">22</a> <a href="#23">23</a>
  </li>
  <br>
  <i>Issues rejected or requiring no action for now:</i>
  <br><br>
  <li>
    Core comments requesting rebase of a TS to C++17: <a href="#3">3</a> <a href="#5">5</a> <a href="#17">17</a>
  </li>
  <li>
    Core comments (no action): <a href="#4">4</a>
  </li>
  <li>
    Core comments (rejected, no consensus for change): <a href="#8">8</a>
  </li>
  <li>
    LWG issues with no wording: <a href="#12">12</a> <a href="#16">16</a> <a href="#19">19</a> <a href="#20">20</a>
  </li>
  <li>
     Evolution issues with no wording: <a href="#1">1</a> <a href="#13">13</a>
</ul>
-->

<!-- ================================================================================ -->
<h2>Evolution/Core Issues</h2>
<hr>

<!-- --------------------------------------------------------------------------------------- -->
<h3><a name="24" href="#24">24.</a>
The specification of initial suspend point does not correctly captures the intent</h3>
<p><b>Section:</b> 11.4.4 [dcl.fct.def.coroutine] <b>Status:</b> Active
 <b>Submitter:</b> Gor Nishanov <b>Opened:</b> 2018-03-08 <b>Last modified:</b> 2018-03-08</p>

<p><b>Issue:</b></p>
<p>
    Common use of the <code>initial_suspend</code> point in asynchronous coroutines is to suspend the coroutine
    during the initial invocation and post a request to resume the coroutine by a different execution agent. 
    If an execution agent at a later point cannot resume the coroutine, for example, because it is being shutdown, 
    an error will be reported to a coroutine by resuming the coroutine
    and subsequently throwing an exception from <code>await_resume</code>.
</p>
<p>
    Currently, the invocation of <code>initial_suspend</code> is specified in [dcl.fct.def.coroutine] as:
</p>
<pre>
  {
    P p;
    co_await p.initial_suspend(); <i>// initial suspend point</i>
    try { F } catch(...) { p.unhandled_exception(); }
  <i>final_suspend</i>:
    co_await p.final_suspend(); <i></i>// final suspend point</i>
  }  
</pre>
<p>
  As specified, an exception from <code>await_resume</code> of <code>initial_suspend</code> will be thrown
  outside of the <code>try-catch</code> and will not be captured by <code>p.unhandled_exception()</code> and
  whoever waits for eventual completion of a coroutine will never learn about its completion.
</p>
<p>
  This is specification defect. The intent is to capture an exception thrown by <code>await_resume</code> of
  an awaitable returned by <code>initial_suspend</code> within the <code>try-catch</code> enclosing of 
  the user authored body <code>F</code>.
</p>

<p><b>Proposed resolution:</b></p>

<p>Add underlying text to paragraph 11.4.4/3 as follows:<p>
  <blockquote>
      <pre>
          {
            P p;
            co_await p.initial_suspend(); <i>// initial suspend point</i>
            try {
              F 
            } catch(...) { p.unhandled_exception(); }
          <i>final_suspend</i>:
            co_await p.final_suspend(); <i></i>// final suspend point</i>
          }  
        </pre>
  </blockquote>
  
  <ins>, except that any exception thrown after the <i>initial suspend point</i> 
    and before the flow of execution reaches <i>F</i> also results in 
    entering the <i>handler</i> of the <i>try-block</i>.</ins>
<!--
 <p><b>Proposed resolution #1 (easy but still does not capture the intent):</b></p>

<p>Modify paragraph 5.3.8/3 as follows:<p>
<blockquote>
    <pre>
        {
          P p;
          <ins>try {</ins>
            co_await p.initial_suspend(); <i>// initial suspend point</i>
          <del>try {</del>
            F 
          } catch(...) { p.unhandled_exception(); }
        <i>final_suspend</i>:
          co_await p.final_suspend(); <i></i>// final suspend point</i>
        }  
      </pre>
</blockquote>
Though this is easy to specify, it violates the design intent.
Specified in this form, it will capture exceptions that occur
in the call to <code>initial_suspend</code> and calls to
<code>await_ready</code> and <code>await_suspend</code> of
the returned awaitable.

<p><b>Proposed resolution #2 (help with wording needed):</b></p>
We probably need to rework 8.4.4/3 from being a pseudocode into a 
description with pure words as the desired behavior is not
directly expressible in pseudocode. </p>
<p>
Here is an unsatisfactory description of the desired behavior in pseudo pseudocode.
<blockquote>
  <pre>
      {
        P p;
        <ins>{</ins>
          <ins>auto &amp;&amp; <i>init</i> = </ins><del>co_await</del> p.initial_suspend(); <i>// initial suspend point</i>
          <ins>// await_ready and await_suspend of expansion of</ins>
          <ins>// co_await of <i>init</i> called here</ins>
          try {
            <ins>// await_resume of expansion of</ins>
            <ins>// co_await of <i>init</i> called here</ins>
              F 
          } catch(...) { p.unhandled_exception(); }
        <ins>}</ins>
      <i>final_suspend</i>:
        co_await p.final_suspend(); <i></i>// final suspend point</i>
      }  
    </pre>
</blockquote>
</p>

-->

<!-- --------------------------------------------------------------------------------------- -->
<h3><a name="25" href="#25">25.</a> Allow unhandled exception escape the user-defined body of 
  the coroutine and give it well defined semantics </h3>
  <p><b>Section:</b> 11.4.4 [dcl.fct.def.coroutine] <b>Status:</b>
    Active
   <b>Submitter:</b> Eric Niebler <b>Opened:</b> 2018-03-10 <b>Last modified:</b> 2018-03-10</p>
  <p><b>Issue:</b></p>
  <p>
    Currently an unhandled exception can never escape the user-authored 
    body of the coroutine. 
  
    <blockquote>
        <pre>
            {
              P p;
              co_await p.initial_suspend(); <i>// initial suspend point</i>
              try {
                F  // user authored body
              } catch(...) { p.unhandled_exception(); }
            <i>final_suspend</i>:
              co_await p.final_suspend(); <i></i>// final suspend point</i>
            }  
          </pre>
    </blockquote>
    
  <p>
  An exception from <code>F</code> is captured by the try-catch and
  a customization point <code>unhandled_exception</code> is called
  where, typically, an exception_ptr is created and propagated to
  the consumer awaiting on async task, or, in case of a generator,
  will be stored in the iterator and be delivered to the user
  when they dereference the iterator.
  </p>
  <p>
  Though the current behavior is perfectly reasonable for asynchronous
  scenarios, it is sub-optimal <!-- creates optimizing difficulties in the case of --> 
  for synchronous generators. Capturing an exception, storing it in an 
  <code>exception_ptr</code> and then rethrowing the exception during,
  say, iterator's <code>operator++</code> is a needless work if the desired
  behavior is to let the exception propagate to the caller
  performing <code>operator++</code> on the iterator of a generator.
   <!-- out if no exception
  was actually thrown by the user-authored body.-->
  </p>
  <p>
    The proposed resolution is to make `unhandled_exception` customization 
    point optional and give well defined behavior to the case when
    exception escapes user-authored body of the coroutine.
  </p>
  <p><b>Proposed Wording:</b></p>
  TBD

<!-- --------------------------------------------------------------------------------------- -->
<h3><a name="26" href="#26">26.</a> Relax requirements on a coroutine_handle passed to <code>await_suspend</code> </h3>
    <p><b>Section:</b> 8.3.8 [expr.await] <b>Status:</b>
      Active
     <b>Submitter:</b> Gor Nishanov <b>Opened:</b> 2018-03-10 <b>Last modified:</b> 2018-03-10</p>
    <p><b>Issue:</b></p>
<p>
  One of the implementation strategies for coroutines is to chop
  original function into as many functions (parts) as there are suspend points.
  In that case, it is possible for a compiler create a unique
  per suspend per function <code>coroutine_handle</code> which 
  <code>resume</code>
  and <code>destroy</code> members can be direct calls to corresponding
  parts of the function.
</p>
<p>Though no compiler is doing it now, we can allow implementors
  to experiment with this approach by relaxing the requirement
  on the <code>coroutine_handle</code> passed 
  to <code>await_suspend</code>.
</p>
<p><b>Proposed wording:</b></p>

Add underlined text to 8.3.8/3.5:

<blockquote>

(3.5) — h is an object of type <ins>convertible to</ins> std::experimental::coroutine_handle&lt;P&gt; referring to the enclosing coroutine.

</blockquote>

<h3><a name="27" href="#27">27.</a> Make suspension in dynamic initializers of <code>static</code> and <code>thread_local</code> local variables ill-formed</h3>
    <p><b>Section:</b> 8.3.8/2 [expr.await] <b>Status:</b>
      Active
     <b>Submitter:</b> Richard Smith <b>Opened:</b> 2018-03-25 <b>Last modified:</b> 2018-03-25</p>
<p><b>Proposed wording:</b></p>

Add underlined text to 8.3.8/2:

<blockquote>
An <i>await-expression</i> shall appear only in a potentially-evaluated
expression within the <i>compound-statement</i> of a <i>function-body</i> 
outside of a <i>handler</i> (Clause 18). 
In a declaration-statement or in
the simple-declaration (if any) of a for-init-statement, an await-expression shall appear only in
an initializer of that declaration-statement or 
simple-declaration<ins> unless it is used to initialize a block-scope variable with static or thread storage duration</ins>.
</blockquote>

<hr>
<!-- ================================================================================ -->
<h2>CWG issues </h2>
<hr>
<!-- --------------------------------------------------------------------------------------- -->
<h3><a name="28" href="#28">28.</a> Simplify stable name for Coroutines to be [def.coroutine] </h3>
    <p><b>Section:</b> 11.4.4 [dcl.fct.def.coroutine] <b>Status:</b>
      Active
     <b>Submitter:</b> Gor Nishanov <b>Opened:</b> 2018-03-10 <b>Last modified:</b> 2018-03-10</p>
<p><b>Proposed wording:</b></p>
[<del>dcl.fct.</del>def.coroutine]

<!--
<h3><a name="29" href="#29">29.</a> Simplify wording for 11.4.4/7 and /8</h3>
    <p><b>Section:</b> 11.4.4 [dcl.fct.def.coroutine] <b>Status:</b>
      Active
     <b>Submitter:</b> Ben Craig <b>Opened:</b> 2018-03-20 <b>Last modified:</b> 2018-03-20</p>
<p><b>Proposed wording improvement:</b></p>

Modify paragraph 7 and 8 of 11.4.4 as follows:

<blockquote>
  <dl>
    <dt>7</dt>
    <dd> An implementation may need to allocate additional storage for a 
    coroutine. This storage is known as the coroutine state and is obtained by calling 
    <ins>the coroutine allocator</ins>. <del> a non-array allocation 
      function (6.7.4.1). The allocation function’s name is looked up in 
      the scope of P. If this lookup fails, the allocation function’s name
       is looked up in the global scope. If the lookup finds an allocation
        function in the scope of P, overload resolution is performed on a 
        function call created by assembling an argument list. 
        The first argument is the amount of space requested, 
        and has type std::size_t. The lvalues p1 ... pn are the succeeding 
        rguments. If no viable function is found, overload resolution is 
        performed again on a function call created by passing just the amount of 
        space required as an argument of type std::size_t.</del>
    </dd>
    </dl>
    
    <dl>
      <dt>8</dt>
    <dd>
    The unqualified-id get_return_object_on_allocation_failure is looked up in the scope of 
    class P by class member access lookup (3.4.5). If a declaration is found, then the 
    result of a call to <ins>the coroutine allocator</ins> <del>an allocation function 
      used to obtain storage for the coroutine state</del> is assumed to return nullptr 
      if it fails to obtain storage <del>, and if a global allocation function is selected, 
        the ::operator new(size_t, nothrow_t) form shall be used</del>. 
        If an allocation function returns nullptr, the coroutine returns control to the 
        caller of the coroutine and the return value is obtained by a call to
         P::get_return_object_on_allocation_failure(). The allocation function used 
         in this case must have a non-throwing noexcept-specification.
    </dd>
    </dl>
</blockquote>
Add new paragraph after paragraph 8 of 11.4.4 as follows:
<blockquote>
  <ins>
    The coroutine allocator is a non array allocation function (6.7.4.1).
    The allocation function’s name is looked up in the scope of P.
    If this lookup fails, the allocation function’s name is looked up in the global
    scope.  If the lookup finds an allocation function in the scope of P,
    overload resolution is performed on a function call created by assembling an
    argument list.  The first argument is the amount of space requested, and has type
    size_t.  If the unqualified-id get_return_object_on_allocation_failure declaration
    is found when looked up in the scope of class P by class member access lookup (6.4.5),
    then the second argument has type <code>nothrow_t</code> and the allocation function
    must have a non-throwing noexcept-specification.  If the unqualified-id 
    <code>get_return_object_on_allocation_failure</code> declaration is not found, 
    then lvalues p1 … pn are the succeeding arguments.  If no matching function is
    found for the size_t, p1 … pn argument list, then overload resolution is performed
    again on a function call created by passing just the amount of space required as an
    argument of type <code>size_t</code>.
  </ins>
</blockquote>
-->
<!--
<p><b>Recommendation:</b></p>

<p> Defer resolution of this issue until proposed change is implemented and tried out on existing code. </p>
-->
<!-- <i>[Accepted: Jacksonville-3/10/2018]</i> -->

<hr>
<!-- ================================================================================ -->
<h2>LEWG/LWG issues </h2>
<hr>
<!-- --------------------------------------------------------------------------------------- -->
<h3><a name="29" href="#29">29.</a>  Absence of <code>const</code> 
  on <code>coroutine_handle::resume()</code> makes lambdas verbose</code></h3>
<p><b>Section:</b> 21.11.2 [coroutine.handle] <b>Status:</b> Active <b>Submitter:</b> (Many) <b>Opened:</b> 2018-03-08 <b>Last modified:</b> 2018-03-08</p>

<p><b>Issue:</b></p>
<p>
    During LEWG/LWG review of Coroutine TS, <code>const</code> on <code>coroutine_handle::resume()</code>
    was removed. While it does follow LEWG/LWG convention of only putting <const>const</const> on
    members that are safe to call concurrently from multiple threads, it does make writing lambdas
    capturing <code>coroutine_handle</code> more verbose. 
</p>
<p>
  <b>used to write: </b><code>[h]{ h.resume();}</code><br>
  <b>now have to write: </b><code>[h]<ins> () mutable </ins>{ h.resume();}</code><br>
</p>
<p> 
  Customers complained and I have recorded this as an issue.
</p>
<!-- <i>[Reject. No consensus for change. Toronto-7/10/2017]</i> -->

<!-- --------------------------------------------------------------------------------------- -->

<!--
<h3><a name="29" href="#29">29.</a>  Make coroutine handle comparison operators stricter</h3>
<p><b>Section:</b> 21.11.2.6 [coroutine.handle.compare] <b>Status:</b> Active <b>Submitter:</b> (Unknown passerby) <b>Opened:</b> 2018-03-08 <b>Last modified:</b> 2018-03-08</p>

<p><b>Issue:</b></p>
<p>
  Coroutine handle comparisons operators are defined with signature:
</p>
<pre>
    constexpr bool operator@(coroutine_handle&lt;&gt; x, coroutine_handle&lt;&gt; y) noexcept;
</pre>
<p>
  where <code>@</code> is one of the operators <code>== != &lt; &gt; &lt;= &gt;=</code>.
</p>
<p>
  This allows comparisons of coroutine handles with unrelated promise types (due to implicit conversion of 
  <code>coroutine_handle&lt;Whatever&gt;</code> to <code>coroutine_handle&lt;&gt;</code>.
  This is probably not beneficial to the user.
  </p><p>The suggestion is to alter
  the coroutine comparison operators to have the signature:
</p>
<pre>
    <ins>template &lt;class Promise&gt;</ins>
    constexpr bool operator@(coroutine_handle&lt;<ins>Promise</ins>&gt; x, coroutine_handle&lt;<ins>Promise</ins>&gt; y) noexcept;
</pre>
<p>
  where <code>@</code> is one of the operators <code>== != &lt; &gt; &lt;= &gt;=</code>.
</p>
-->
<!-- <i>[Reject. No consensus for change. Toronto-7/10/2017]</i> -->


</body>
</html>
