<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>issues</title>

	<style>
	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 {color:#00A000}
	del {color:#A00000}
	</style>

</head>
<body>

<address align=right>
Document number: N2771=08-0281<br>
<br>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br>
2008-09-19
</address>
<hr>

<h1 align=center>LWG Issues</h1>

<hr>

<h3><a name="882"></a>882. <tt>duration</tt> non-member arithmetic requirements</h3>
<p><b>Section:</b> 20.8.3.5 [time.duration.nonmember] <b>Status:</b> Ready
 <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2008-09-08</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm">N2661</a>
specified the following requirements for the non-member <tt>duration</tt>
arithmetic:
</p>

<blockquote>

<pre>
template &lt;class Rep1, class Period, class Rep2&gt;
  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  operator*(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s);
</pre>
<blockquote>
<i>Requires:</i> Let <tt>CR</tt> represent the <tt>common_type</tt> of <tt>Rep1</tt> and
<tt>Rep2</tt>.  Both <tt>Rep1</tt> and <tt>Rep2</tt> shall be implicitly convertible
to CR, diagnostic required.
</blockquote>

<pre>
template &lt;class Rep1, class Period, class Rep2&gt;
  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  operator*(const Rep1&amp; s, const duration&lt;Rep2, Period&gt;&amp; d);
</pre>

<blockquote>
<i>Requires:</i> Let <tt>CR</tt> represent the <tt>common_type</tt> of
<tt>Rep1</tt> and <tt>Rep2</tt>. Both <tt>Rep1</tt> and <tt>Rep2</tt>
shall be implicitly convertible to <tt>CR</tt>, diagnostic required.
</blockquote>

<pre>
template &lt;class Rep1, class Period, class Rep2&gt;
  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  operator/(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s);
</pre>

<blockquote>
<i>Requires:</i> Let <tt>CR</tt> represent the <tt>common_type</tt> of
<tt>Rep1</tt> and <tt>Rep2</tt>. Both <tt>Rep1</tt> and <tt>Rep2</tt> shall be
implicitly convertible to <tt>CR</tt>, and <tt>Rep2</tt> shall not be an
instantiation of <tt>duration</tt>, diagnostic required.
</blockquote>

</blockquote>

<p>
During transcription into the working paper, the requirements clauses on these
three functions was changed to:
</p>

<blockquote>
<i>Requires:</i> <tt>CR(Rep1, Rep2)</tt> shall exist. Diagnostic required.
</blockquote>

<p>
This is a non editorial change with respect to
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm">N2661</a>
as user written representations which are used in <tt>duration</tt> need not be
implicitly convertible to or from arithmetic types in order to interoperate with
<tt>duration</tt>s based on arithmetic types.  An explicit conversion will do
fine for most expressions as long as there exists a <tt>common_type</tt> specialization
relating the user written representation and the arithmetic type.  For example:
</p>

<blockquote><pre>
class saturate
{
public:
  explicit saturate(long long i);
  ...
};

namespace std {

template &lt;&gt;
struct common_type&lt;saturate, long long&gt;
{
    typedef saturate type;
};

template &lt;&gt;
struct common_type&lt;long long, saturate&gt;
{
    typedef saturate type;
};

}  // std

millisecond ms(3);  // integral-based duration
duration&lt;saturate, milli&gt; my_ms = ms;  // ok, even with explicit conversions
my_ms = my_ms + ms;                    // ok, even with explicit conversions
</pre></blockquote>

<p>
However, when dealing with multiplication of a duration and its representation,
implicit convertibility is required between the rhs and the lhs's representation
for the member <tt>*=</tt> operator:
</p>

<blockquote><pre>
template &lt;class Rep, class Period = ratio&lt;1&gt;&gt; 
class duration { 
public: 
   ...
   duration&amp; operator*=(const rep&amp; rhs);
   ...
};
...
ms *= 2;               // ok, 2 is implicitly convertible to long long
my_ms *= saturate(2);  // ok, rhs is lhs's representation
my_ms *= 2;            // error, 2 is not implicitly convertible to saturate
</pre></blockquote>

<p>
The last line does not (and should not) compile.  And we want non-member multiplication
to have the same behavior as member arithmetic:
</p>

<blockquote><pre>
my_ms = my_ms * saturate(2);  // ok, rhs is lhs's representation
my_ms = my_ms * 2;            // <em>should be</em> error, 2 is not implicitly convertible to saturate
</pre></blockquote>

<p>
The requirements clauses of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm">N2661</a>
make the last line an error as expected.  However the latest working draft at
this time
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf">N2723</a>)
allows the last line to compile.
</p>

<p>
All that being said, there does appear to be an error in these requirements clauses
as specified by 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm">N2661</a>.
</p>

<blockquote>
<i>Requires:</i> ... <em>Both</em> <tt>Rep1</tt> and <tt>Rep2</tt> shall be implicitly convertible
to CR, diagnostic required.
</blockquote>

<p>
It is not necessary for both <tt>Rep</tt>s to be <i>implicitly</i> convertible to
the <tt>CR</tt>.  It is only necessary for the rhs <tt>Rep</tt> to be implicitly
convertible to the <tt>CR</tt>.  The <tt>Rep</tt> within the <tt>duration</tt>
should be allowed to only be explicitly convertible to the <tt>CR</tt>.  The
explicit-conversion-requirement is covered under 20.8.3.7 [time.duration.cast].
</p>



<p><b>Proposed resolution:</b></p>
<p>
Change the requirements clauses under 20.8.3.5 [time.duration.nonmember]:
</p>

<blockquote>

<pre>
template &lt;class Rep1, class Period, class Rep2&gt;
  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  operator*(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s);
</pre>

<blockquote>
<i>Requires:</i> <del><tt>CR(Rep1, Rep2)</tt> shall exist.</del>
<ins><tt>Rep2</tt> shall be implicitly convertible to <tt>CR(Rep1, Rep2)</tt>.</ins>
Diagnostic required.
</blockquote>

<pre>
template &lt;class Rep1, class Period, class Rep2&gt;
  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  operator*(const Rep1&amp; s, const duration&lt;Rep2, Period&gt;&amp; d);
</pre>

<blockquote>
<i>Require<ins>s</ins><del>d behavior</del>:</i> <del><tt>CR(Rep1, Rep2)</tt> shall exist.</del>
<ins><tt>Rep1</tt> shall be implicitly convertible to <tt>CR(Rep1, Rep2)</tt>.</ins>
Diagnostic required.
</blockquote>

<pre>
template &lt;class Rep1, class Period, class Rep2&gt;
  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  operator/(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s);
</pre>

<blockquote>
<i>Requires:</i> <del><tt>CR(Rep1, Rep2)</tt> shall exist</del>
<ins><tt>Rep2</tt> shall be implicitly convertible to <tt>CR(Rep1, Rep2)</tt></ins>
and <tt>Rep2</tt> shall not
be an instantiation of <tt>duration</tt>. Diagnostic required.
</blockquote>

</blockquote>

<hr>

<h3><a name="858"></a>858. Wording for Minimal Support for Garbage Collection</h3>
<p><b>Section:</b> 20.7.12.6 [util.dynamic.safety] <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Pete Becker  <b>Date:</b> 2008-06-21</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Ready">Ready</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The first sentence of the Effects clause for <tt>undeclare_reachable</tt> seems
to be missing some words. I can't parse
</p>
<blockquote>
... for all non-null <tt>p</tt> referencing the argument is no longer declared reachable...
</blockquote>
<p>
I take it the intent is that <tt>undeclare_reachable</tt> should be called only
when there has been a corresponding call to <tt>declare_reachable</tt>. In
particular, although the wording seems to allow it, I assume that code
shouldn't call <tt>declare_reachable</tt> once then call <tt>undeclare_reachable</tt>
twice.
</p>
<p>
I don't know what "shall be live" in the Requires clause means.
</p>
<p>
In the final Note for <tt>undeclare_reachable</tt>, what does "cannot be
deallocated" mean? Is this different from "will not be able to collect"?
</p>

<p>
For the wording on nesting of <tt>declare_reachable</tt> and
<tt>undeclare_reachable</tt>, the words for locking and unlocking recursive
mutexes probably are a good model.
</p>


<p><b>Proposed resolution:</b></p>
<p>
In 20.7.12.6 [util.dynamic.safety]
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm">N2670</a>,
Minimal Support for Garbage Collection)
</p>
<p>
Add at the beginning, before paragraph 39
</p>

<blockquote>
A complete object is <i>declared reachable</i> while the number of calls
to <tt>declare_reachable</tt> with an argument referencing the object exceeds the
number of <tt>undeclare_reachable</tt> calls with pointers to the same complete
object.
</blockquote>

<p>
Change paragraph 42 (Requires clause for <tt>undeclare_reachable</tt>)
</p>

<blockquote>
If <tt>p</tt> is not null, <del><tt>declare_reachable(p)</tt> was previously called</del>
<ins>the complete object referenced by <tt>p</tt> shall have
been previously declared reachable</ins>, and shall
be live <ins>(3.8 [basic.life])</ins> from the time of the call until the last <tt>undeclare_reachable(p)</tt>
call on the object.
</blockquote>

<p>
Change the first sentence in paragraph 44 (Effects clause for
<tt>undeclare_reachable</tt>):
</p>

<blockquote>
<i>Effects:</i> 
<del>Once the number of calls to
<tt>undeclare_reachable(p)</tt> equals the number of calls to
<tt>declare_reachable(p)</tt>
for all non-null <tt>p</tt> referencing
the argument is no longer declared reachable.  When this happens,
pointers to the object referenced by p may not be subsequently
dereferenced.</del>
<ins>
After a call to <tt>undeclare_reachable(p)</tt>, if <tt>p</tt> is not null and the object <tt>q</tt>
referenced by <tt>p</tt> is no longer declared reachable, then
dereferencing any pointer to <tt>q</tt> that is not safely derived
results in undefined behavior.
</ins> ...
</blockquote>

<p>
Change the final note:
</p>
<p>
[<i>Note:</i> It is expected that calls to <tt>declare_reachable(p)</tt>
will consume a small amount of memory<ins>, in addition to that occupied
by the referenced object, </ins> until the matching call to
<tt>undeclare_reachable(p)</tt> is encountered. <del>In addition, the
referenced object cannot be deallocated during this period, and garbage
collecting implementations will not be able to collect the object while
it is declared reachable.</del> Long running programs should arrange
that calls <ins>for short-lived objects</ins> are matched. <i>--end
note</i>]
</p>


<hr>


</body>
</html>
