<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2221: No formatted output operator for nullptr</title>
<meta property="og:title" content="Issue 2221: No formatted output operator for nullptr">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2221.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#C++17">C++17</a> status.</em></p>
<h3 id="2221"><a href="lwg-defects.html#2221">2221</a>. No formatted output operator for <code>nullptr</code></h3>
<p><b>Section:</b> 31.7.6 <a href="https://wg21.link/output.streams">[output.streams]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Matt Austern <b>Opened:</b> 2012-12-07 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>3
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>

<p>
When I write 
</p>
<blockquote><pre>
std::cout &lt;&lt; nullptr &lt;&lt; std::endl;
</pre></blockquote>
<p>
I get a compilation error, "ambiguous overload for '<code>operator&lt;&lt;</code>' in '<code>std::cout &lt;&lt; nullptr</code>'". 
As far as I can tell, the compiler is right to issue that error. There are inserters for <code>const void*</code>, 
<code>const char*</code>, <code>const signed char*</code>, and <code>const unsigned char*</code>, and none for 
<code>nullptr_t</code>, so the expression really is ambiguous.
<p/>
<em>Proposed wording</em>:
<p/>
The obvious library solution is to add a <code>nullptr_t</code> overload, which would be defined something like
</p>
<blockquote><pre>
template&lt;class C, class T&gt;
basic_ostream&lt;C, T&gt;&amp; operator&lt;&lt;(basic_ostream&lt;C, T&gt;&amp; os, nullptr_t) 
{ 
  return os &lt;&lt; (void*) nullptr; 
}
</pre></blockquote>
<p>
We might also consider addressing this at a core level: add a special-case language rule that addresses all 
cases where you write <code>f(nullptr)</code> and <code>f</code> is overloaded on multiple pointer types. (Perhaps 
a tiebreaker saying that <code>void*</code> is preferred in such cases.)
</p>

<p><i>[2016-01-18, comments from Mike and Ville collected by Walter Brown]</i></p>

<p>
<b>Mike Miller</b>: "Changing overload resolution sounds like something that should be
considered by EWG before CWG [&hellip;]"
<p/>
<b>Ville</b>: "Agreed, such a change would be Evolutionary. Personally, I think it would also be wrong, because 
I don't see how <code>void*</code> is the right choice to prefer in the case of code that is currently ambiguous. 
Sure, it would solve this particular library issue, but it seemingly has wider repercussions. If LWG really wants 
to, EWG can certainly discuss this issue, but I would recommend solving it on the LWG side (which doesn't mean 
that the standard necessarily needs to change, I wouldn't call it far-fetched to NAD it)."
</p>

<p><i>[2016-08 Chicago]</i></p>

<p>Zhihao recommends NAD:</p>
<p>
<code>nullptr</code> is printable if being treated as <code>void*</code>, but causes
UB if being treated as <code>char cv*</code>. Capturing this ambigurity
at compile time and avoid a runtime UB is a good thing.
</p>

<p><i>[2016-08 Chicago]</i></p>

<p>Tues PM: General agreement on providing the overload; discussion on what it should say.</p>
<p>Polls:<br/>
Matt's suggestion (in the issue): 2/0/6/2/2/<br/>
Unspecified output: 3/2/5/0/1<br/>
Specified output: 1/1/6/3/0</p>
<p>Move to Open</p>

<p><i>[2016-08 Chicago]</i></p>

<p>
The group consensus is that we only output <code>nullptr</code> because
it is of a fundamental type, causing problems in functions doing
forwarding, and we don't want to read it back.
</p>
<p>Fri PM: Move to Tentatively Ready</p>


<p id="res-2221"><b>Proposed resolution:</b></p>
<p>
This wording is relative to N4606
</p>

<ol>
<li><p>Insert the signature into 31.7.6.2 <a href="https://wg21.link/ostream">[ostream]</a>, class template <code>basic_ostream</code> synopsis, as follows:</p>

<blockquote class="note">
<p>
[<i>Drafting notes:</i> Why member?  Don't want to define a new category of inserters just for this.]
</p>
</blockquote>

<blockquote>
<pre>
namespace std {
  template &lt;class charT, class traits = char_traits&lt;charT&gt; &gt;
  class basic_ostream
    : virtual public basic_ios&lt;charT, traits&gt; {
  public:
    [&hellip;]
    basic_ostream&lt;charT, traits&gt;&amp; operator&lt;&lt;(const void* p);
    <ins>basic_ostream&lt;charT, traits&gt;&amp; operator&lt;&lt;(nullptr_t);</ins>
    basic_ostream&lt;charT, traits&gt;&amp; operator&lt;&lt;(
      basic_streambuf&lt;char_type, traits&gt;* sb);
    [&hellip;]
  };
</pre>
</blockquote>
</li>

<li><p>Append the following new paragraphs to 31.7.6.3.3 <a href="https://wg21.link/ostream.inserters">[ostream.inserters]</a>:</p>

<blockquote>
<pre>
basic_ostream&lt;charT, traits&gt;&amp; operator&lt;&lt;
  (basic_streambuf&lt;charT, traits&gt;* sb);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-10- <i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
<ins>basic_ostream&lt;charT, traits&gt;&amp; operator&lt;&lt;(nullptr_t);</ins>
</pre>
<blockquote>
<p>
<ins>-??- <i>Effects:</i> Equivalent to <code>return *this &lt;&lt; s;</code> where
<code>s</code> is an implementation-defined NTCTS.</ins>
</p>
</blockquote>

</blockquote>
</li>
</ol>





</body>
</html>
