<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - constructing an ios_base::Init object clobbers stream state"
   href="https://bugs.llvm.org/show_bug.cgi?id=43300">43300</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>constructing an ios_base::Init object clobbers stream state
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>richard-llvm@metafoo.co.uk
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Constructing an object of type std::ios_base::Init is supposed to have no
effect when the IO streams have already been initialized. In libc++, that is
not the case.

Testcase:


#include <iostream>

int main() {
    std::cout << "hello, " << std::boolalpha;
    std::ios_base::Init init_streams;
    std::cout << true << " world!";
}


... should print "hello true world!" but with libc++ prints "hello 1 world!".

This also presumably means that a multithreaded program that constructs an Init
object has a data race. This seems straightforward to fix by adding a static
one-time initialization guard to the iso_base::Init constructor.

It might also be reasonable to maintain an atomic count of the number of extant
Init objects so that the flushes in the destructor are only run when the last
one is destroyed, as [ios.init]/4 requires. I think that the current destructor
behavior might even result in observable nonconformance in programs that call
cout.rdbuf(stream) and observe when stream sees writes.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>