    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: 5 Reasons NOT to Use std::ostream for Human-Readable Output</title>
        <link>https://members.accu.org/index.php/articles/2486</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #144 - April 2018</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c384/">o144</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-384/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+384/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;5 Reasons NOT to Use std::ostream for Human-Readable Output</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 03 April 2018 16:42:39 +01:00 or Tue, 03 April 2018 16:42:39 +01:00</p>
<p><strong>Summary:</strong>&nbsp;C++â€™s ostream can be hard to use. Sergey Ignatchenko suggests we use the {fmt} library instead.</p>
<p><strong>Body:</strong>&nbsp;<p class="EditorIntro">Disclaimer: as usual, the opinions within this article are those of â€˜No Bugsâ€™ Hare, and do not necessarily coincide with the opinions of the translators and <em>Overload</em> editors; also, please keep in mind that translation difficulties from Lapine (like those described in [<a href="#[Loganberry04]">Loganberry04) mi</a>ght have prevented an exact translation. In addition, the translator and <em>Overload</em> expressly disclaim all responsibility from any action or inaction resulting from reading this article.</p>

<h2>This is NOT yet another printf-vs-cout debate</h2>

<p>First of all, to avoid being beaten really hard, I have to say that I am perfectly aware of all the arguments presented in favour of 30+-year-old <code>std::ostream</code> (that is, compared to <code>printf()</code> which arguably comes from 50+-years-old BCPL) â€“ and moreover, that I am NOT going to argue for <code>printf()</code> in this article.</p>

<p>The arguments usually used to push <code>cout</code> over <code>printf</code>, are the following [<a href="#[C++ FAQ]">C++ FAQ</a>]:</p>

<ol>
	<li><code>iostream</code> is type-safe.
		<p>â€˜No Bugsâ€™ comment: I am the last person to argue about this one.</p>
	</li>
	
	<li>it is less error-prone (referring to reducing redundancy)
		<p>â€˜No Bugsâ€™ comment: while saying that reducing redundancy is the same as being less error-prone is a bit of stretch in general (in quite a few cases, redundancy is exactly what keeps us from making silly mistakes), in the context of the <code>cout</code>-vs-<code>printf()</code> debate, I can agree with it.</p>
	</li>
	
	<li>it is extensible (allowing you to specify your own classes to be printed).
		<p>â€˜No Bugsâ€™ comment: very nice to have indeed.</p>
	</li>
	
	<li><code>std::ostream</code> and <code>std::istream</code> are inheritable, which means you can have other user-defined things that look and act like streams, yet that do whatever strange and wonderful things you want.
		<p>â€˜No Bugsâ€™ comment: TBH, I fail to see why being inheritable is an advantage <em>per se</em>; especially as extending existing functionality doesnâ€™t depend on inheritance (at least, as long as no virtual functions are involved, and I donâ€™t see many of them in <code>std::ostream</code> as such). The best I can make out of this one is understanding it as â€˜being able to provide my own underlying streambuf to be used by <code>ostream</code>â€™, which does qualify as an advantage (at least over <code>printf()</code>,which doesnâ€™t provide such an option at all: more on this below). </p>
	</li>
</ol>

<p>Once again, I am NOT going to argue with the points above (doing so would certainly start another World Flame War); instead, I just want to take them as a starting point (clarifying the one which isnâ€™t obvious to me, so it is specific enough for our purposes).</p>

<h2>ostream is far from perfect</h2>

<p>Even with all its advantages over 50+year-old <code>printf()</code>, <code>ostream</code> is still far from perfect â€“ at least for human-readable outputs.</p>

<p>Ok, so far we have seen the good side of <code>ostream</code>; however (conspicuously omitted from [<a href="#[C++ FAQ]">C++ FAQ</a>]), it has quite a few downsides too, especially if we concentrate on specific use cases for <code>std::ostream</code>. A whole bunch of very popular use cases for <code>ostream</code>s involve formatting output which is intended to be read by human beings. Two popular examples of such formatting include:</p>

<ul>
	<li>Formatting output which is shown to the end-user (usually in some kind of UI, whether graphical or not).</li>
	
	<li>Formatting output which is sent to text-based logs (which tends to apply both to the Client-Side and to the Server-Side).
		<p>Note that, strictly speaking, Server-Side text-based logs can be divided into (a) text logs used for monitoring purposes, and (b) text logs for post-mortem analysis, with a recent movement towards making (a) structured rather than free-text based. Still, I am sure that (b) is there to stay as free-text based, so the text logging use case will still stand even if the movement towards structured logging for monitoring purposes succeeds.</p>
	</li>
</ul>

<p>As it said on the tin, weâ€™re going to concentrate on output intended for human beings â€“ and while weâ€™re at it, weâ€™ll keep in mind the two major use cases above. And, as I am going to present a point of view which â€“ while it was articulated previously in [<a href="#[Moria]">Moria</a>] and [<a href="#[NoBugs]">NoBugs</a>] â€“ is certainly not as popular as the four points above (yet?), I am going to be significantly more verbose than [<a href="#[C++ FAQ]">C++ FAQ</a>].</p>

<p>So, in no particular order, here they are: the major drawbacks of <code>ostream</code>s when used to format human-readable outputs.</p>

<h3>Drawback number 1: i18n</h3>

<p class="quote">â€œVantage number one!â€ said the Bi-Coloured-Python-Rock-Snake.â€œYou couldnâ€™t have done that with a mere-smear nose. Try and eat a little now.â€<br/>~ Bi-Coloured-Python-Rock-Snake from â€˜Just So Storiesâ€™</p>

<p>The first major problem with using <code>ostream</code>-like chevron-based formatting for human-readable strings is internationalization. Letâ€™s take a look at a piece of code which formats a simple message for the UI of an online poker game: </p>

<pre class="programlisting">
  some_ostream &lt;&lt; winner.name &lt;&lt; &quot; shows &quot; 
    &lt;&lt;   winner.cards &lt;&lt; &quot; and wins $&quot; 
    &lt;&lt; pot_size / 100 &lt;&lt; &quot;.&quot; &lt;&lt; std::setw(2) 
    &lt;&lt; std::setfill('0') &lt;&lt; pot_size % 100;
    // we have pot_size stored in cents, but have to
    // display it in a more conventional manner</pre>
	
<p><em>NB: for our purposes, letâ€™s skip the discussion about localizing currency signs and dots-vs-commas; in particular, for online games, the former happens to be not a question of locality, but a question of what currency this site really uses, and nobody gives a damn about the latter.</em></p>

<p>When trying to translate this code, it happens to suffer from two huuuuge (actually, bordering on insurmountable) problems, namely:</p>

<ul>
	<li>Translations NEVER work by translating isolated words. In other words, there is no point in asking a translator to translate a fragment such as â€œshowsâ€ into a different language. Such translations (even if translators are silly enough to do them) will never work, simply because for translations context is everything â€“ but with the code above, the context is buried within C++ code, and is not easily extractable (we DONâ€™T want to teach translators C++, do we?)</li>
	
	<li>Moreover, the order of the parameters we want to substitute (the <code>winner.name</code>, <code>winner.cards</code>, and <code>pot_size</code>) can be <em>different</em> in a human-readable language other than English; with the code above, <em>this would mean that potentially we have to rewrite the code for each target human language</em> (ok, for 3 parameters, we can say that there arenâ€™t more than 3!=6 possible combinations we have to code, but IMNSHO it is still 6x too much). </li>
</ul>

<p>Now, letâ€™s come to specific examples; to illustrate better than <code>ostream</code> alternatives throughout this article, I (by definition) have to use something different from <code>ostream</code>. However, as I donâ€™t want to use <code>printf()</code> for this purpose (to make it even more clear that I am NOT advocating a return to <code>printf()</code>) Iâ€™ll use one of Pythonâ€™s format options (the curly braced one) to illustrate how things can be done. In Python, our formatting looks as follows:</p>

<pre class="programlisting">
  print(&quot;{0} shows {1} and wins ${2}.{3:02d}&quot;
  .format(winner.name,winner.cards,pot_size/100,
  pot_size%100))</pre>

<p>Here, we have our string (with placeholders in curly brackets) and can easily pass it to the translation team . While we will still have to replace our original literal with something read from a file at runtime, it is still nothing compared to the need to rewrite the whole <code>ostream</code>-based thing (with all the possible variations for the order of parameters). Most importantly, with Python-like formatting, both our i18-related points above are addressed:</p>

<ul>
	<li>Our original phrase to be translated exists as a self-contained literal. As practice shows, these tend to be perfectly translatable (in some cases, comments about the meaning of {0}, {1}, and {2} may need to be added to help translators better understand the context â€“ but thatâ€™s about it, and most real-world phrases are already more or less self-contained).</li>
	
	<li>If there is a need to use a different order of parameters in the translated version, this can <em>easily</em> be done by the translator without any involvement from developers (which, BTW is exactly the way it should be).</li>
</ul>

<h3>Drawback number 2: multithreading</h3>

<p class="quote">â€œVantage number two!â€ said the Bi-Coloured-Python-Rock-Snake.â€œYou couldnâ€™t have done that with a mere-smear nose. Donâ€™t you think the sun is very hot here?â€<br />~ Bi-Coloured-Python-Rock-Snake from â€˜Just So Storiesâ€™</p>

<p>While i18n is mostly in the realm of strings intended for some kind of UI, our second drawback is mostly related to logging in a multithreaded environment.</p>

<p><em>NB: for this drawback, Iâ€™ll use different example code â€“ which is more typical for logging than for formatting for a UI, and thatâ€™s where this particular problem is more likely to manifest itself.</em></p>

<p>If you have ever written innocent-looking code such as </p>

<pre class="programlisting">
  logging_stream &lt;&lt; &quot;Event #&quot; &lt;&lt; std::setw(8) 
  &lt;&lt; std::setfiller('0') &lt;&lt; std::hex &lt;&lt; event_id 
  &lt;&lt; &quot;: a=&quot; &lt;&lt; std::dec &lt;&lt; a &lt;&lt; &quot; b=&quot; &lt;&lt; b &lt;&lt; &quot;\n&quot;;</pre>
  
<p>and then tried to run it in two different threads <em>simultaneously</em>, you know that the code above can easily generate all kinds of weird outputs, including such beauties as </p>

<pre class="programlisting">
  Event #Event #0089a1b2c3d4e5f6: a=12: a= b=
  b=345678
  &lt;\n&gt;
  &lt;\n&gt;</pre>
  
<p>In addition to being completely unreadable, there is absolutely no way to figure out how digits from â€˜345678â€™ were distributed between one <code>a</code> and two <code>b</code>s coming from different threads (and in which order BTW). </p>

<p>The reason for it is simple: with <code>ostream</code>, instead of calling one implementation function, weâ€™re calling <em>several separated</em> <code>&lt;&lt;</code> operators; in turn, this means that the largest possible synchronization unit for <code>cout</code> stream is not a <em>phrase</em> (~= â€œone line we want to outputâ€), but merely each of the items between <code>&lt;&lt;</code> chevrons. This inevitably leads to potentially having outputs such as the one above. </p>

<p>Sure, somebody can say â€œHey, you should place a mutex lock above that lineâ€ â€“ and it would help; however, placing such mutex locks is not just error-prone, but error-prone-squared because (a) it is easy to forget to place it, and (b) it is even easier to forget to unlock it <em>right after the </em><code>cout</code> <em>line</em> (which, in turn, can easily lead to a <em>huuuuge</em> performance degradation for no reason whatsoever).</p>

<p>A better alternative is proposed in [<a href="#[P0053R7]">P0053R7</a>], where a special temporary object (an instance of <code>class osyncstream</code>, which is derived from <code>ostream</code>) is constructed on top of our real <code>ostream</code> object (such as <code>cout</code>). Then, the <code>osyncstream</code> object will buffer all the output written to it via <code>&lt;&lt;</code> operators, and will write to the underlying <code>cout</code> only at the point of being destructed. This ensures that all the output written to <code>osyncstream</code> is guaranteed to be written in one piece &lt;phew /&gt;. IMO, <code>osyncstream</code> is indeed a pretty good workaround for this particular problem (at any rate, <em>much</em> better than mutexes), but it still has the following significant issues:</p>

<ol style="list-style-type:lower-alpha;">
	<li>unless we limit ourselves to one-line uses of our <code>osyncstream</code> object (more precisely, to creating an <code>osyncstream</code> instance only temporarily), writing to the underlying stream in the destructor becomes rather counterintuitive, and it is easy to forget to limit the scope of our <code>osyncstream</code>, which can lead to reordering of whole â€˜phrasesâ€™ in our log (it wonâ€™t look as bad as reordering of the words shown above, but can still cause significant confusion when reading the logs);</li>
	
	<li>extra buffering wonâ€™t come for free (especially as the current proposal seems to use allocations &lt;ouch !/&gt;); and</li>
	
	<li>[<a href="#[P0053R7]">P0053R7</a>] wonâ€™t help with the other issues discussed in the article (though maybe it might help to deal with our next drawback â€“ sticky flags â€“ too).</li>
</ol>

<h3>Drawback number 3: sticky flags</h3>

<p>Anyone who has tried to do some formatting which goes beyond the textbook using cout has encountered a huuuge problem that </p>

<p style="margin-left:1em"><em>With </em><code>ostream</code><em>, formatting modifiers (such as hex-vs-dec, filler, etc.) are considered an attribute of the stream, not of the output operation.</em></p>

<p>In other words: formatting flags, once applied, â€˜stickâ€™ to the stream. This, in turn, means that if you forget to revert them back, youâ€™ll obtain an unexpectedly formatted output (and of course, it wonâ€™t be noticed until production, and will manifest itself in exactly the place where it causes the maximum possible damage).</p>

<p>This problem becomes especially bad in scenarios where we have one global stream (such as <code>cout</code> or a log file). <em>In fact, it means that our formatting flags become a part of the GLOBAL mutable program state</em> â€“ and last time I checked, everybody of sane mind (including those people who are arguing for <code>cout</code>), agrees that global mutable state is a Bad Thingâ„¢.</p>

<p>In fact, this problem is so bad, that Boost even has a special class to deal with it! With Boostâ€™s <code>ios_flags_saver</code>, our code will look like:</p>

<pre class="programlisting">
  boost::io::ios_flags_saver ifs(logging_stream);
  logging_stream &lt;&lt; &quot;Event #&quot; &lt;&lt; std::setw(8) 
    &lt;&lt; std::setfiller('0') &lt;&lt; std::hex &lt;&lt; event_id
    &lt;&lt; &quot;: a=&quot; &lt;&lt; std::dec &lt;&lt; a &lt;&lt; &quot; b=&quot; &lt;&lt; b 
    &lt;&lt; &quot;\n&quot;;</pre>
	
<p>However, even with such an RAII-based workaround, once again it is error-prone: it is easy to forget to add the <code>ios_flags_saver</code> â€“ especially if the policy is to use it only when some sticky manipulators are applied (and if our project Guidelines say â€˜always use <code>ios_flags_saver</code>â€™, it would be a violation of the â€˜not paying for what we donâ€™t useâ€™ principle, and would still be rather error-prone).</p>

<h3>Drawback number 4: readability</h3>

<p class="quote">â€œVantage number three!â€ said the Bi-Coloured-Python-Rock-Snake. â€œYou couldnâ€™t have done that with a mere-smear nose. Now how do you feel about being spanked again?â€<br />~ Bi-Coloured-Python-Rock-Snake from â€˜Just So Storiesâ€™</p>

<p>Now, letâ€™s try to write down our full examples of formatting human-readable output using <code>ostream</code> (while keeping all the considerations above in mind). To summarize, our rather simple formatting code examples will look like Listing 1.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
// UI formatting
// guard is probably NOT required here, as weâ€™re not
// likely to work with UI strings from multiple
// threads
boost::io::ios_flags_saver ifs(some_ostream);
some_ostream &lt;&lt; winner.name &lt;&lt; &quot; shows &quot; 
  &lt;&lt; winner.cards &lt;&lt; &quot; and wins $&quot; 
  &lt;&lt; pot_size / 100 &lt;&lt; &quot;.&quot; &lt;&lt; std::setw(2) 
  &lt;&lt; std::setfill('0') &lt;&lt; pot_size % 100;

//logging
std::lock_guard&lt;std::mutex&gt;
  guard(logging_stream_mutex);
boost::io::ios_flags_saver ifs(logging_stream);
logging_stream &lt;&lt; &quot;Event #&quot; &lt;&lt; std::setw(8) 
  &lt;&lt; std::setfiller('0') &lt;&lt; std::hex &lt;&lt; event_id 
  &lt;&lt; &quot;: a=&quot; &lt;&lt; std::dec &lt;&lt; a &lt;&lt; &quot; b=&quot; 
  &lt;&lt; b &lt;&lt; &quot;\n&quot;;
guard.unlock();//as discussed above, we donâ€™t want
// to keep lock longer than really necessary
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>When looking at the code in Listing 1, I cannot help but think that it <span style="text-decoration:line-through;">has been spanked by the Elephantâ€™s Child</span> has fallen from the Ugly Treeâ„¢ (hitting all the ugly branches on the way down). And whenever somebody tells me that this code is <em>readable</em>, I can only ask them to compare it with the way the same thing is done in pretty much all other languages but C++ (yes, even in C â€“ though using an unmentionable function); in particular, in Python it would look like Listing 2.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
  //UI formatting
  print(&quot;{0} shows {1} and wins ${2}.{3:02d}&quot;
  .format(winner.name,winner.cards,pot_size/100,
     pot_size%100))

  //Logging
  print(&quot;Event #{0:08x}: a={1:d} b={2:d}&quot;
    .format(event_id, a, b))
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>Formally speaking, the <code>ostream</code>-based code above has between 2x and 4x more characters, and between 2.5x and 5x more non-whitespace YACC tokens, than the demonstrated format-string based alternative, and while brevity does not necessarily equate to better readability, in the case of a 300â€“400% overhead, it usually does. </p>

<p>And if looking at it informally, with just (hopefully) an unbiased programmerâ€™s eyes:</p>

<p style="margin-left:1em"><em>I think the answer to â€˜which of the two pieces of code above can be seen as readableâ€™ is very obvious </em></p>

<p>(hint: I do NOT think that the <code>ostream</code>-based one qualifies as such).</p>

<h3>Drawback number 4.5: writing customized underlying stream could be better</h3>

<p>Yet another drawback of the <code>ostream</code> (BTW, this one stands regardless of whether it is being used for human-readable output) is that the process of writing the underlying stream is rather non-obvious and is seriously error-prone. I donâ€™t want to go into details here (it is way too long since the last time I did it myself) but [<a href="#[Tomaszewski]">Tomaszewski</a>] describes what I remember pretty well, including observations such as â€œ<em>Properly deriving from </em><code>std::streambuf</code><em> is not easy and intuitive because its interface is complicated</em>â€, and making â€œ<em>a very subtle bug which took me several hours to detect</em>â€. </p>

<p>To be perfectly honest, it is still MUCH better than not being unable to write a customized stream <em>at all</em> (as is the case for <code>printf()</code>), but â€“ as I noted above â€“ I am not speaking in terms of <code>printf()</code>, and being prone to subtle bugs is certainly not a good thing for those who need to rewrite an underlying <code>streambuf</code>.</p>

<h3>Drawback number 5: something MUCH better exists</h3>

<p>All the musing about the drawbacks of <code>ostream</code> would remain a rather pointless ranting if not for one thing: a library <em>exists</em> which has <em>all</em> the <code>ostream</code>-like advantages listed in [<a href="#[C++ FAQ]">C++ FAQ</a>], and <em>none</em> of the drawbacks listed above. </p>

<p>Actually, there are several such libraries (Boost format, FastFormat, tinyformat, {fmt}, and FollyFormat â€“ and probably something else which I have forgotten to mention). I have to note that, personally, I donâ€™t really care too much <em>which</em> one of the competing new-generation format libraries makes it into the standard (except, probably, for Boost format, which is way too resource-intensive when compared to the alternatives). In general, I (alongside with a very significant portion of the C++ community) just want <em>some</em> standard and better-than-<code>iostream</code> way of formatting human-readable data.</p>

<p>Out of such newer formatting libraries I happen to know {fmt} by Victor Zverovich the best, <em>and</em> it certainly looks very good, satisfying <em>all</em> the points from C++ FAQ, and avoiding <em>all</em> the <code>iostream</code> problems listed above. As {fmt} is also the only new-generation library with an active WG21 proposal [<a href="#[P0645R1]">P0645R1</a>], it is the one Iâ€™m currently keeping my fingers crossed for. (NB: in the past, there was another proposal, [<a href="#[N3506]">N3506</a>], but it looks pretty much abandoned).  </p>

<p>In this article, I am not going to go into lengthy discussion about {fmt} vs the alternatives â€“ but will just mention that with {fmt}, our examples will look like:</p>

<pre class="programlisting">
fmt::print(&quot;{0} shows {1} and wins ${2}.{3:02d}&quot;,
  winner.name,winner.cards,pot_size/100,
  pot_size%100);
  //this is C++, folks!

  fmt::print(&quot;Event #{0:08x}: a={1:d} b={2:d}&quot;,
    event_id, a, b);</pre>
	
<p>This alone allows us to avoid most of the problems listed above (and FWIW, Iâ€™d argue it is even more readable than Python); in addition, {fmt} is type-safe, extensible, supports both <code>ostream</code> and <code>FILE*</code> as underlying streams (with the ability to add your own stream easily), beats <code>ostream</code> performance-wise, et cetera, et cetera.</p>

<h2>C++ Developer Community on formatting approaches</h2>

<p>After all the theorizing about different formatting approaches, letâ€™s see what real-world developers are saying about the different libraries available for this purpose. First, I have to note that even before the advent of the new generation of format libraries â€“ <em>and in spite of enormous pressure exerted by quite a few C++ committee members via their numerous publications in favour of</em> <code>cout</code> â€“ real-world C++ developers were badly split on the question â€œwhat is better â€“ <code>cout</code> or <code>printf()</code>â€ (see, for example, statistics in [<a href="#[StackOverflow]">StackOverflow</a>] and [<a href="#[Quora]">Quora</a>]). Now, with {fmt} available, developers <em>seem</em> to agree that it is the best real-world option out there [<a href="#[Reddit]">Reddit</a>]; just two quotes from <em>top-upvoted</em> comments (which prove nothing, of course, but do count as anecdotal evidence):</p>

<ul>
	<li><em>I am already using </em><code>{fmt}</code><em> all over my projects but having it in the </em><code>std</code><em> would be great.</em></li>
	
	<li><em>So happy this is steadily transitioning in </em><code>std</code><em>. One of the best formatting (and i/o) libs out there overall. Even without the localization argument, Iâ€™ve always found iostreams to be less convenient.</em></li>
</ul>

<p><em>Yes, I know it sounds like a bad commercial, but I am pretty sure these comments are genuine.</em></p>

<p>Oh, and if somebody in WG21 still has any doubts about what-C++ developers want to use for human-readable formatting, please let me know: Iâ€™ll organize a survey to get more formal numbers. </p>

<h2>Conclusion</h2>

<p>We took a look at <code>std::ostream</code> and issues with its real-world usage when formatting output intended for human beings. As a side note, we observed that most of the problems with <code>std::ostream</code> in this context arise from it working as a stream (either char stream, or word/token stream) while human beings tend to communicate in phrases or sentences, and one thing <code>std::ostream</code> is badly lacking is support for those phrases/sentences so ubiquitous in the real world.</p>

<p>Moreover, as we noted, there is more than one library out there which not only has all the advantages of <code>ostream</code> over <code>printf()</code> but also fixes <em>all</em> the drawbacks of the <code>ostream</code> we listed above. IMNSHO, there is no question of â€˜what is better to useâ€™ (that is, for human-readable outputs). This means that our (= â€˜real-world C++ developersâ€™) course of action is very clear:</p>

<ul>
	<li>Start using {fmt} as much as possible (well, you may choose some other library over {fmt}, but IMO fragmentation is a bad thing for such a library, so unless you have some very specific requirements, I suggest using {fmt} as a <em>de facto</em> standard). Aside from the direct benefits weâ€™ll get from using it, it might help to iron out any subtle issues left (such as â€˜how to implement <em>compile-time</em> type safetyâ€™), and to make the proposal to WG21 more solid.</li>
	
	<li>Keep our fingers crossed hoping that WG21 <em>will</em> take the P0645R1 proposal into the standard (though with the pace of changes making through WG21, I will have to pray really hard that it happens before I retire &lt;sad-wink /&gt;).</li>
</ul>

<p><img src="/content/images/journals/ol144/Ignatchenko/Ignatchenko-01.png" /></p>

<h2>References</h2>

<p class="bibliomixed"><a id="[C++ FAQ]"></a>[C++ FAQ] C++ FAQ, <a href="https://isocpp.org/wiki/faq/input-output#iostream-vs-stdio ">https://isocpp.org/wiki/faq/input-output#iostream-vs-stdio </a></p>

<p class="bibliomixed"><a id="[fmt]"></a>[fmt] A modern formatting library, <a href="https://github.com/fmtlib/fmt">https://github.com/fmtlib/fmt</a> </p>

<p class="bibliomixed"><a id="[Loganberry04]"></a>[Loganberry04] David â€˜Loganberryâ€™, Frithaes! â€“ an Introduction to Colloquial Lapine!, <a href="http://bitsnbobstones.watershipdown.org/lapine/overview.html">http://bitsnbobstones.watershipdown.org/lapine/overview.html</a></p>

<p class="bibliomixed"><a id="[Moria]"></a>[Moria] IOStream Is Hopelessly Broken, <a href="https://www.moria.us/articles/iostream-is-hopelessly-broken/">https://www.moria.us/articles/iostream-is-hopelessly-broken/</a></p>

<p class="bibliomixed"><a id="[N3506]"></a>[N3506] Zhihao Yuan, A printf-like Interface for the Streams Library </p>

<p class="bibliomixed"><a id="[NoBugs]"></a>[NoBugs] â€˜No Bugsâ€™ Hare, #CPPCON2017. Day 1. Hope to get something-better-than-chevron-hell, <a href="http://ithare.com/cppcon2017-day-1-hope-to-get-something-better-than-chevrone-hell">http://ithare.com/cppcon2017-day-1-hope-to-get-something-better-than-chevrone-hell</a>/</p>

<p class="bibliomixed"><a id="[P0053R7]"></a>[P0053R7] Lawrence Crowl, Peter Sommerlad, Nicolai Josuttis, Pablo Halpern, C++ Synchronized Buffered Ostream, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0053r7.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0053r7.pdf</a></p>

<p class="bibliomixed"><a id="[P0645R1]"></a>[P0645R1] Victor Zverovich, Lee Howes. Text Formatting. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0645r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0645r1.html</a></p>

<p class="bibliomixed"><a id="[Quora]"></a>[Quora] When would you use fprintf instead of cerr/iostream in C++?,  <a href="https://www.quora.com/When-would-you-use-fprintf-instead-of-cerr-iostream-in-C++">https://www.quora.com/When-would-you-use-fprintf-instead-of-cerr-iostream-in-C++</a></p>

<p class="bibliomixed"><a id="[Reddit]"></a>[Reddit] A Chance to Get Readable Formatting: {fmt}, <a href="https://www.reddit.com/r/cpp/comments/72krvy/a_chance_to_get_readable_formatting_fmt/">https://www.reddit.com/r/cpp/comments/72krvy/a_chance_to_get_readable_formatting_fmt/</a></p>

<p class="bibliomixed"><a id="[StackOverflow]"></a>[StackOverflow] â€˜printfâ€™ vs. â€˜coutâ€™ in C++, <a href="https://stackoverflow.com/questions/2872543/printf-vs-cout-in-c">https://stackoverflow.com/questions/2872543/printf-vs-cout-in-c</a></p>

<p class="bibliomixed"><a id="[Tomaszewski]"></a>[Tomaszewski] Krzysztof Tomaszewski, Deriving from std::streambuf,  <a href="https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/">https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/</a></p>

<h2>Acknowledgement</h2>

<p>Cartoon by Sergey Gordeev from Gordeev Animation Graphics, Prague</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
