<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2214: Clarify basic_ios::init call restrictions</title>
<meta property="og:title" content="Issue 2214: Clarify basic_ios::init call restrictions">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2214.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#Open">Open</a> status.</em></p>
<h3 id="2214"><a href="lwg-active.html#2214">2214</a>. Clarify <code>basic_ios::init</code> call restrictions</h3>
<p><b>Section:</b> 31.5.4.2 <a href="https://wg21.link/basic.ios.cons">[basic.ios.cons]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Andrey Semashev <b>Opened:</b> 2012-11-09 <b>Last modified:</b> 2021-07-31</p>
<p><b>Priority: </b>4
</p>
<p><b>View all other</b> <a href="lwg-index.html#basic.ios.cons">issues</a> in [basic.ios.cons].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
There is an ambiguity in how <code>std::basic_ios::init</code> method (31.5.4.2 <a href="https://wg21.link/basic.ios.cons">[basic.ios.cons]</a>)
can be used in the derived class. The Standard only specify the state of the <code>basic_ios</code>
object after the call completes. However, in <code>basic_ios</code> default constructor description
(31.5.4.2 <a href="https://wg21.link/basic.ios.cons">[basic.ios.cons]</a>) there is this sentence:
</p>
<blockquote><p>
<i>Effects</i>: Constructs an object of class <code>basic_ios</code> (31.5.2.8 <a href="https://wg21.link/ios.base.cons">[ios.base.cons]</a>)
leaving its member objects uninitialized. The object shall be initialized by calling <code>basic_ios::init</code>
before its first use or before it is destroyed, whichever comes first; otherwise the behavior is undefined.
</p></blockquote>
<p>
This restriction hints that <code>basic_ios::init</code> should be called exactly
once before the object can be used or destroyed, because <code>basic_ios::init</code>
may not know whether it was called before or not (i.e. whether its members are actually
uninitialized or are initialized by the previous call to <code>basic_ios::init</code>). There
is no such restriction in the <code>basic_ios::init</code> preconditions so it is not clear whether it is
allowed to call <code>basic_ios::init</code> multiple times or not.
<p/>
This problem has already affected publicly available implementations.
For example, Microsoft Visual C++ STL introduces a memory leak if
<code>basic_ios::init</code> is called multiple times, while GCC 4.7 and STLPort
reinitialize the <code>basic_ios</code> object correctly without memory leak or any
other undesired effects. There was a discussion of this issue on Boost
<a href="http://article.gmane.org/gmane.comp.lib.boost.devel/235659">developers mailing list</a>,
and there is a <a href="https://sourceforge.net/apps/trac/boost-log/ticket/2#comment:4">test case
that reproduces the problem</a>. The test case is actually a bug report for my Boost.Log library,
which attempts to cache <code>basic_ostream</code>-derived objects internally to avoid expensive construction
and destruction. My stream objects allowed resetting the stream buffer pointers the stream
is attached to, without requiring to destroy and construct the stream.
<p/>
My personal view of the problem and proposed resolution follows.
<p/>
While apparently the intent of <code>basic_ios::init</code> is to provide a way to
initialize <code>basic_ios</code> after default construction, I see no reason to
forbid it from being called multiple times to reinitialize the stream.
Furthermore, it is possible to implement a conforming <code>basic_ios</code> that
does not have this restriction.
<p/>
The quoted above section of the Standard that describes the effects of
the default constructor is misleading. The Standard does not mandate
any data members of <code>basic_ios</code> or <code>ios_base</code> (31.5.2 <a href="https://wg21.link/ios.base">[ios.base]</a>), which
it derives from. This means that the implementation is allowed to use
non-POD data members with default constructors that initialize the
members with particular default values. For example, in the case of
Microsoft Visual C++ STL the leaked memory is an <code>std::locale</code> instance
that is dynamically allocated during <code>basic_ios::init</code>, a raw pointer to
which is stored within ios_base. It is possible to store e.g. an
<code>unique_ptr</code> instead of a raw pointer as a member of <code>ios_base</code>, the smart
pointer will default initialize the underlying raw pointer on default
construction and automatically destroy the allocated object upon being
reset or destroyed, which would eliminate the leak and allow
<code>basic_ios::init</code> to be called multiple times. This leads to conclusion
that the default constructor of <code>basic_ios</code> cannot leave "its member
objects uninitialized" but instead performs default initialization of
the member objects, which would mean the same thing in case of POD types.
<p/>
However, I feel that restricting <code>ios_base</code> and <code>basic_ios</code> members to
non-POD types is not acceptable. Since multiple calls to <code>basic_ios::init</code> are
not forbidden by the Standard, I propose to correct the <code>basic_ios</code> default
constructor description so that it is allowed to destroy <code>basic_ios</code> object
without calling <code>basic_ios::init</code>. This would imply that any raw members of
<code>basic_ios</code> and <code>ios_base</code> should be initialized to values suitable for
destruction (essentially, this means only initializing raw pointers to NULL). The new
wording could look like this:
</p>
<blockquote><p>
<i>Effects</i>: Constructs an object of class <code>basic_ios</code> (31.5.2.8 <a href="https://wg21.link/ios.base.cons">[ios.base.cons]</a>)
initializing its member objects to unspecified state, only suitable for <code>basic_ios</code> destruction.
The object shall be initialized by calling <code>basic_ios::init</code> before its first use; otherwise
the behavior is undefined.
</p></blockquote>
<p>
This would remove the hint that <code>basic_ios::init</code> must be called exactly
once. Also, this would remove the requirement for <code>basic_ios::init</code> to
be called at all before the destruction. This is also an important issue because
the derived stream constructor may throw an exception before it manages to call
<code>basic_ios::init</code> (for example, if the streambuf constructor throws), and
in this case the <code>basic_ios</code> destructor has undefined behavior.
<p/>
To my mind, the described modification is sufficient to resolve the issue. But to
emphasize the possibility to call <code>basic_ios::init</code> multiple times, a remark
or a footnote for <code>basic_ios::init</code> postconditions could be added to explicitly
state the semantics of calling it multiple times. The note could read as follows:
</p>
<blockquote><p>
The function can be called multiple times during the object lifetime. Each subsequent
call reinitializes the object to the described in postconditions initial state.
</p></blockquote>

<p><i>[2013-04-20, Bristol]</i></p>


<p>
Alisdair: The current wording is unclear but the proposed resolution is wrong
<p/>
Solution: Clarify that <code>init</code> must be called once and only once. Move then to review.
</p>

<p><i>[2021-07-29 Tim comments]</i></p>

<p>
The requirement that "<code>init</code> must be called once and only once" conflicts
with the disposition of LWG <a href="lwg-closed.html#135" title="basic_iostream doubly initialized (Status: NAD)">135</a><sup><a href="https://cplusplus.github.io/LWG/issue135" title="Latest snapshot">(i)</a></sup>.
</p>


<p id="res-2214"><b>Proposed resolution:</b></p>
<p>This wording is relative to N3485.</p>

<ol>
<li><p>Edit 31.5.4.2 <a href="https://wg21.link/basic.ios.cons">[basic.ios.cons]</a> as indicated:</p>
<blockquote><pre>
basic_ios();
</pre>
<blockquote>
<p>
-2- <i>Effects</i>: Constructs an object of class <code>basic_ios</code> (31.5.2.8 <a href="https://wg21.link/ios.base.cons">[ios.base.cons]</a>)
<del>leaving its member objects uninitialized</del><ins>initializing its member objects to unspecified state,
only suitable for <code>basic_ios</code> destruction</ins>. The object shall be initialized by calling
<code>basic_ios::init</code> before its first use <del>or before it is destroyed, whichever comes first</del>;
otherwise the behavior is undefined.
</p>
</blockquote>
<pre>
void init(basic_streambuf&lt;charT,traits&gt;* sb);
</pre><blockquote>
<p>
<i>Postconditions</i>: The postconditions of this function are indicated in Table 128.
<p/>
<ins>-?- <i>Remarks</i>: The function can be called multiple times during the object lifetime. Each subsequent
call reinitializes the object to the described in postconditions initial state.</ins>
</p>
</blockquote>
</blockquote>
</li>
</ol>






</body>
</html>
