Skip to content

constructing an ios_base::Init object clobbers stream state #42645

@zygoloid

Description

@zygoloid
mannequin
Bugzilla Link 43300
Resolution FIXED
Resolved on Sep 13, 2019 08:28
Version unspecified
OS Linux
CC @mclow

Extended Description

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

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.

Metadata

Metadata

Assignees

Labels

bugzillaIssues migrated from bugzillalibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions