<HTML>
<HEAD>
   <style>
     <!--
       P.indented {margin-left: 4em}
       XMP.indented {margin-left: 4em}
     -->
   </style>
   <TITLE>
       Core issue 654 wording
   </TITLE>
</HEAD>

<BODY>

<TABLE ALIGN=RIGHT CELLSPACING=0 CELLPADDING=0 >
<TR>
	<TD ALIGN=RIGHT>Document number:</TD>
	<TD>&nbsp;N2656=08-0166</TD>
</TR>

<TR>
	<TD ALIGN=RIGHT>Date:</TD>
	<TD>&nbsp;2008-06-10</TD>
</TR>
<TR>
	<TD ALIGN=RIGHT>Author:</TD>
	<TD>&nbsp;J. Stephen Adamczyk, Edison Design Group</TD>
</TR>

<TR>
	<TD></TD>
	<TD>&nbsp;<TT>jsa@edg.com</TT></TD>
</TR>

</TABLE>

<BR CLEAR=ALL>

<CENTER>
<H2>
Core issue 654 wording
</H2>
</center>

<p>
Core issue 654 recommends three additions to the <tt>nullptr</tt> functionality:
<le>
<li>
An integral zero constant should be convertible to <tt>nullptr_t</tt>.
</li>
<li>
A <tt>nullptr_t</tt> value should be convertible to <tt>bool</tt>, but only
in the "contextually converted to bool" contexts.
</li>
<li>
A <tt>nullptr_t</tt> value should be convertible to an integral type via
a <tt>reinterpret_cast</tt>.
</li>
</le>
</p>
<p>
In discussion of the second bullet in the CWG on June 9, we decided that
consistency between pointers and <tt>nullptr_t</tt> was desirable, i.e.,
a <tt>nullptr_t</tt> value should be convertible to <tt>bool</tt> in
exactly the same contexts that a pointer is convertible to
<tt>bool</tt>.  There was some disagreement over whether this should
be all contexts (as is true for pointers in the current standard),
or whether it should be only the "contextually converted to bool"
contexts (which, for pointer cases,
would require breaking some code that is currently
valid).  We are going forward with allowing
the conversions in all contexts, and we have asked implementers
to try the breaking change for pointers and report back on the
effect on existing code bases.  If the change seems harmless
(or beneficial), we may produce a separate proposal at the
next meeting to limit conversions of both <tt>nullptr_t</tt>
and pointers to bool to the "contextually converted to bool"
(really, direct-initialization) contexts.
</p>


<h3>
Working Draft changes
</h3>

<p>
Change 4.10 [conv.ptr] paragraph 1 as follows:
</p>

<BLOCKQUOTE>
A <em>null pointer constant</em> is an integral constant expression (5.19)
rvalue of integer type that evaluates to zero or an rvalue of type
<tt>std::nullptr_t</tt>. A null pointer constant can be converted to
a pointer type; the result is the <em>null pointer value</em>
of that type and is distinguishable from every other value of pointer
to object or pointer to function type. Two null pointer values of the
same type shall compare equal. The conversion of a null pointer constant
to a pointer to cv-qualified type is a single conversion, and not the
sequence of a pointer conversion followed by a qualification conversion (4.4).
<b>A null pointer constant of integral type can be converted to an rvalue
of type <tt>std::nullptr_t</tt>.  [<em>Note: </em>The resulting rvalue
is not a null pointer value.]</b>
</BLOCKQUOTE>

<p>
[Drafting note: It wasn't clear before whether a <tt>nullptr_t</tt> rvalue
is a null pointer value.  I have made it clear it isn't, on the logic that
it's not a pointer; it could equally be considered a null pointer to member.
I checked the uses of "null pointer value," and saw no cases
where this would be a problem.]
</p>

<p>
Change 4.12 [conv.bool] paragraph 1 as follows:
</p>

<BLOCKQUOTE>
An rvalue of arithmetic, unscoped enumeration, pointer, or pointer to member
type can be converted to an rvalue of type <tt>bool</tt>. A zero value,
null pointer value, or null member pointer value is converted to
<tt>false</tt><b>;</b> any other value is converted to <tt>true</tt>.
<b>An rvalue of type <tt>std::nullptr_t</tt> can be converted to an
rvalue of type <tt>bool</tt>; the resulting value is <tt>false</tt>.</b>
</BLOCKQUOTE>

<p>
[Drafting note: Note the <em>en passant</em> addition of
a missing semicolon.]
</p>

<p>
Changes 5.2.10 [expr.reinterpret.cast] paragraphs 4 and 9 as follows:
</p>

<BLOCKQUOTE>
A pointer can be explicitly converted to any integral type large enough
to hold it. The mapping function is implementation-defined.
[ <em>Note:</em> it is intended to be unsurprising to those who know
the addressing structure of the underlying machine. <em>--end note</em> ]
<b>A value of type <tt>std::nullptr_t</tt> can be explicitly converted
to an integral type; the conversion has the same meaning and validity as
a conversion of <tt>(void *)0</tt> to the integral type.
[ <em>Note:</em> a <tt>reinterpret_cast</tt> cannot be used to convert
a value of any type to the type <tt>std::nullptr_t</tt>.
<em>--end note</em> ]</b>
</BLOCKQUOTE>

<BLOCKQUOTE>
...
</BLOCKQUOTE>

<BLOCKQUOTE>
The null pointer value (4.10) is converted to the null pointer value
of the destination type.
[ <em>Note:</em> <strike>A null pointer constant
of integral type is not necessarily converted
to a null pointer value.
(A null pointer constant of type <tt>std::nullptr_t</tt>
cannot appear as the operand of <tt>reinterpret_cast</tt>,
nor can any value be converted by
 <tt>reinterpret_cast</tt> to type
<tt>std::nullptr_t</tt>.)</strike>
<b>A null pointer constant of type <tt>std::nullptr_t</tt> cannot be
converted to a pointer type, and a null pointer constant of
integral type is not necessarily converted to a null pointer
value.</b> <em>--end note</em> ]
</BLOCKQUOTE>

<p>
[Drafting note:  13.3.3.1.1 [over.best.ics] table 11 covers the
cost of standard conversions and does not need to be updated for
this change.  Because of the sections in which they are defined
(4.10 and 4.12), 0 converted to <tt>nullptr_t</tt> is a pointer conversion,
and <tt>nullptr_t</tt> converted to <tt>bool</tt> is a boolean conversion, and
they get the appropriate cost in overload resolution.]
</p>

<h3>End of document.</h3>

</body>
</html>
