<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2011: Unexpected output required of strings</title>
<meta property="og:title" content="Issue 2011: Unexpected output required of strings">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2011.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++14">C++14</a> status.</em></p>
<h3 id="2011"><a href="lwg-defects.html#2011">2011</a>. Unexpected output required of strings</h3>
<p><b>Section:</b> 27.4.4.4 <a href="https://wg21.link/string.io">[string.io]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> James Kanze <b>Opened:</b> 2010-07-23 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#string.io">issues</a> in [string.io].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>
<p>
What should the following code output? 
</p>

<blockquote><pre>
#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;iomanip&gt;

int main() 
{ 
   std::string test("0X1Y2Z"); 
   std::cout.fill('*'); 
   std::cout.setf(std::ios::internal, std::ios::adjustfield); 
   std::cout &lt;&lt; std::setw(8) &lt;&lt; test &lt;&lt; std::endl; 
} 
</pre></blockquote>

<p>
I would expect "<code>**0X1Y2Z</code>", and this is what the compilers I have access
to (VC++, g++ and Sun CC) do.  But according to the standard, it should be
"<code>0X**1Y2Z</code>":
</p>

<p>
27.4.4.4 <a href="https://wg21.link/string.io">[string.io]</a>&#47;5: 
</p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_ostream&lt;charT, traits&gt;&amp;
    operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const basic_string&lt;charT,traits,Allocator&gt;&amp; str);
</pre><blockquote><p>
<i>Effects:</i> Behaves as a formatted output function (31.7.6.3.1 <a href="https://wg21.link/ostream.formatted.reqmts">[ostream.formatted.reqmts]</a>). After constructing 
a <code>sentry</code> object, if this object returns <code>true</code> when converted to a value of type <code>bool</code>, 
determines padding as described in 28.3.4.3.3.3 <a href="https://wg21.link/facet.num.put.virtuals">[facet.num.put.virtuals]</a>, then inserts the resulting sequence of
characters seq as if by calling <code>os.rdbuf()-&gt;sputn(seq, n)</code>, where <code>n</code> is the larger of 
<code>os.width()</code> and <code>str.size()</code>; then calls <code>os.width(0)</code>.
</p></blockquote>
</blockquote>

<p>
28.3.4.3.3.3 <a href="https://wg21.link/facet.num.put.virtuals">[facet.num.put.virtuals]</a>&#47;5: 
</p>

<blockquote>
<p>
[&hellip;] 
</p>

<p>
<b>Stage 3:</b> A local variable is initialized as
</p>

<blockquote><pre>
fmtflags adjustfield= (flags &amp; (ios_base::adjustfield));
</pre></blockquote>

<p>
The location of any padding is determined according to Table 88. 
</p>

<p>
If <code>str.width()</code> is nonzero and the number of <code>charT</code>'s in the
sequence after stage 2 is less than <code>str.width()</code>, then enough fill
characters are added to the sequence at the position indicated for padding to
bring the length of the sequence to <code>str.width()</code>. <code>str.width(0)</code>
is called.
</p>

<table border="1">
<caption>Table 88 &mdash; Fill padding</caption>
<tr>
<th>State</th>
<th>Location</th>
</tr>

<tr>
<td><code>adjustfield == ios_base::left</code></td>
<td>pad after</td>
</tr>

<tr>
<td><code>adjustfield == ios_base::right</code></td>
<td>pad before</td>
</tr>

<tr>
<td><code>adjustfield == internal</code> and a sign occurs in the representation</td>
<td>pad after the sign</td>
</tr>

<tr>
<td><code>adjustfield == internal</code> and representation after stage 1 began with 0x or 0X</td>
<td>pad after x or X</td>
</tr>

<tr>
<td><i>otherwise</i></td>
<td>pad before</td>
</tr>
</table>

</blockquote>

<p>
Although it's not 100% clear what "the sequence after stage 2" should mean here,
when there is no stage 2, the only reasonable assumption is that it is the
contents of the string being output.  In the above code, the string being output
is "<code>0X1Y2Z</code>", which starts with "<code>0X</code>", so the padding should be
inserted "after x or X", and not before the string. I believe that this is a
defect in the standard, and not in the three compilers I tried.
</p>

<p><i>[
2010 Batavia (post meeting session)
]</i></p>

<p>
Consensus that all known implementations are consistent, and disagree with the
standard. Preference is to fix the standard before implementations start trying
to conform to the current spec, as the current implementations have the preferred
form. Howard volunteered to drught for Madrid, move to Open.
</p>

<p><i>[2011-03-24 Madrid meeting]</i></p>


<p>
Daniel Kr&uuml;gler volunteered to provide wording, interacting with Dietmar and
Bill. 
</p>

<p><i>[2011-06-24 Daniel comments and provides wording]</i></p>


<p>
The same problem applies to the output provided by <code>const char*</code> and similar
character sequences as of 31.7.6.3.4 <a href="https://wg21.link/ostream.inserters.character">[ostream.inserters.character]</a> p. 5. and even for
single character output (!) as described in 31.7.6.3.4 <a href="https://wg21.link/ostream.inserters.character">[ostream.inserters.character]</a> p. 1,
just consider the character value '-' where '-' is the sign character. In this case
Table 91 &mdash; "Fill padding" requires to pad after the sign, i.e. the output
for the program
</p>
<blockquote><pre>
#include &lt;iostream&gt;
#include &lt;iomanip&gt;

int main() 
{ 
   char c = '-'; 
   std::cout.fill('*'); 
   std::cout.setf(std::ios::internal, std::ios::adjustfield); 
   std::cout &lt;&lt; std::setw(2) &lt;&lt; c &lt;&lt; std::endl; 
} 
</pre></blockquote>

<p>
According to the current wording this program should output "<code>-*</code>", but
all tested implementations output "<code>*-</code>" instead.

<p/>
I suggest to replace the reference to 28.3.4.3.3.3 <a href="https://wg21.link/facet.num.put.virtuals">[facet.num.put.virtuals]</a> in all three places. 
It is not very complicated to describe the padding rules for simple character sequences "inline". 
A similar approach is used as for the <code>money_put</code> functions.
</p>

<p><i>[
2011 Bloomington
]</i></p>


<p>
Move to Review, the resolution seems correct but it would be nice if some factoring of the
common words were proposed.
</p>

<p><i>[2012, Kona]</i></p>

<p>
Moved to Tentatively Ready by the post-Kona issues processing subgroup.
</p>
<p>
While better factoring of the common words is desirable, it is also editorial and
should not hold up the progress of this issue.  As the edits impact two distinct
clauses, it is not entirely clear what a better factoring should look like.
</p>

<p><i>[2012, Portland: applied to WP]</i></p>




<p id="res-2011"><b>Proposed resolution:</b></p>
<p>
The new wording refers to the FDIS numbering.
</p>
<ol>
<li><p>Change 27.4.4.4 <a href="https://wg21.link/string.io">[string.io]</a>&#47;5 as indicated:</p>
<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_ostream&lt;charT, traits&gt;&amp;
    operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os,
               const basic_string&lt;charT,traits,Allocator&gt;&amp; str);
</pre><blockquote><p>
-5- <i>Effects</i>: Behaves as a formatted output function ([ostream.formatted.reqmts]). After constructing a sentry object,
if this object returns <code>true</code> when converted to a value of type <code>bool</code>, determines padding as <del>described
in [facet.num.put.virtuals],</del><ins>follows: A <code>charT</code> character sequence is produced, initially consisting of 
the elements defined by the range <code>[str.begin(), str.end())</code>. If <code>str.size()</code> is less than <code>os.width()</code>, 
then enough copies of <code>os.fill()</code> are added to this sequence as necessary to pad to a width of <code>os.width()</code> 
characters. If <code>(os.flags() &amp; ios_base::adjustfield) == ios_base::left</code> is <code>true</code>, the fill characters 
are placed after the character sequence; otherwise, they are placed before the character sequence. T</ins><del>t</del>hen 
inserts the resulting sequence of characters <code>seq</code> as if by calling <code>os.rdbuf()-&gt;sputn(seq, n)</code>, where 
<code>n</code> is the larger of <code>os.width()</code> and <code>str.size()</code>; then calls <code>os.width(0)</code>.
</p></blockquote></blockquote>
</li>

<li><p>Change 31.7.6.3.4 <a href="https://wg21.link/ostream.inserters.character">[ostream.inserters.character]</a>&#47;1 as indicated (An additional editorial
fix is suggested for the first prototype declaration):</p>
<blockquote><pre>
template&lt;class charT, class traits&gt;
  basic_ostream&lt;charT,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;charT,traits&gt;&amp; out,
                                          charT c<del>}</del><ins>)</ins>;
template&lt;class charT, class traits&gt;
  basic_ostream&lt;charT,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;charT,traits&gt;&amp; out,
                                          char c);
<i>// specialization</i>
template&lt;class traits&gt;
  basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;char,traits&gt;&amp; out,
                                         char c);
<i>// signed and unsigned</i>
template&lt;class traits&gt;
  basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;char,traits&gt;&amp; out,
                                         signed char c);
template&lt;class traits&gt;
  basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;char,traits&gt;&amp; out,
                                         unsigned char c);
</pre><blockquote><p>
-1- <i>Effects</i>: Behaves like a formatted inserter (as described in [ostream.formatted.reqmts]) of <code>out</code>. 
After a sentry object is constructed it inserts characters. In case <code>c</code> has type <code>char</code> and the 
character type of the stream is not <code>char</code>, then the character to be inserted is <code>out.widen(c)</code>; 
otherwise the character is <code>c</code>. Padding is determined as <del>described in [facet.num.put.virtuals]</del><ins>follows: 
A character sequence is produced, initially consisting of the insertion character. If <code>out.width()</code> is greater
than one, then enough copies of <code>out.fill()</code> are added to this sequence as necessary to pad to a width of 
<code>out.width()</code> characters. If <code>(out.flags() &amp; ios_base::adjustfield) == ios_base::left</code> is <code>true</code>, 
the fill characters are placed after the insertion character; otherwise, they are placed before the insertion 
character</ins>. <del><code>width(0)</code> is called.</del> The insertion character and any required padding are 
inserted into <code>out</code><ins>; then calls <code>os.width(0)</code></ins>.
</p></blockquote></blockquote>
</li>

<li><p>Change 31.7.6.3.4 <a href="https://wg21.link/ostream.inserters.character">[ostream.inserters.character]</a>&#47;5 as indicated:</p>
<blockquote><pre>
template&lt;class charT, class traits&gt;
  basic_ostream&lt;charT,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;charT,traits&gt;&amp; out,
                                          const charT* s);
template&lt;class charT, class traits&gt;
  basic_ostream&lt;charT,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;charT,traits&gt;&amp; out,
                                          const char* s);
template&lt;class traits&gt;
  basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;char,traits&gt;&amp; out,
                                         const char* s);
template&lt;class traits&gt;
  basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;char,traits&gt;&amp; out,
                                         const signed char* s);
template&lt;class traits&gt;
  basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;char,traits&gt;&amp; out,
                                         const unsigned char* s);
</pre><blockquote><p>
[&hellip;]
<p/>
-5- Padding is determined as <del>described in [facet.num.put.virtuals]. The <code>n</code> characters starting at <code>s</code> 
are widened using <code>out.widen</code> ([basic.ios.members])</del><ins>follows: A character sequence is produced, initially 
consisting of the elements defined by the <code>n</code> characters starting at <code>s</code> widened using 
<code>out.widen</code> ([basic.ios.members]). If <code>n</code> is less than <code>out.width()</code>, then enough copies of 
<code>out.fill()</code> are added to this sequence as necessary to pad to a width of <code>out.width()</code> characters. 
If <code>(out.flags() &amp; ios_base::adjustfield) == ios_base::left</code> is <code>true</code>, the fill characters are 
placed after the character sequence; otherwise, they are placed before the character sequence</ins>. The 
widened characters and any required padding are inserted into <code>out</code>. Calls <code>width(0)</code>.
</p></blockquote></blockquote>
</li>
</ol>






</body>
</html>
