This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/12855] Thread safety problems in ios_base::Init
- From: "peturr02 at ru dot is" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 4 Nov 2003 09:17:52 -0000
- Subject: [Bug libstdc++/12855] Thread safety problems in ios_base::Init
- References: <20031031094301.12855.peturr02@ru.is>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12855
------- Additional Comments From peturr02 at ru dot is 2003-11-04 09:17 -------
> std::ios_base::Init should never be used outside global objects.
What about logging? Consider:
Foo.h:
============================
class Foo
{
public:
Foo();
~Foo():
};
============================
foo.cc:
============================
#include <iostream>
Foo::Foo()
{
std::clog << "Foo constructed\n";
}
Foo::~Foo()
{
std::clog << "Foo destroyed\n";
}
============================
If we have another source file:
a.cc:
============================
#include "foo.h"
static Foo foo;
============================
This is unsafe, because foo may be constructed before the ios_base::Init
object in foo.cc, and Foo::Foo() may access clog before it is constructed.
This can be fixed by modifying foo.cc:
============================
#include <iostream>
Foo::Foo()
{
std::ios_base::Init init;
std::clog << "Foo constructed\n";
}
Foo::~Foo()
{
std::ios_base::Init init;
std::clog << "Foo destroyed\n";
}
============================
The standard guarantees that clog will be constructed before the constructor
of init finishes, so the problem has been fixed. However, unless
ios_base::Init is threadsafe, this means that Foo can no longer be used safely
in threaded programs.