Hello.
I need some quick help here: Are local static variables thread-safe?
I'm thinking about something like this:
Is it ok?Code:MyClass& MyClass::GetInst()
{
static MyClass myObj;
return myObj;
}
Printable View
Hello.
I need some quick help here: Are local static variables thread-safe?
I'm thinking about something like this:
Is it ok?Code:MyClass& MyClass::GetInst()
{
static MyClass myObj;
return myObj;
}
in c++03 no, it isn't
in c++0x yes, it is ( threads entering concurrently in GetInst will wait for the initialization of myObj to complete )
in VC++2010, AFAIK no, it isn't, being not implemented yet
in latest gcc, I don't know; anybody ?
So, the c++ standard says nothing about thread-safety of local static variables?
>> So, the c++ standard says nothing about thread-safety of local static variables?
>> in c++03 no
>> in c++11 yes
They are thread-safe in the latest standard.
gg
And what about the static data members?
I suppose, but I'm not 100% sure, that they're ok. Am I right?
And, is there a workaround to making a class singletone besides using pointers?
ie besides this:
Code:class MyClass
{
MyClass* m_pInst;
....
};
MyClass* MyClass::GetInst()
{
if (!m_pInst) m_pInst = new MyClass;
return m_pInst;
}
Static data members are initialized the same as a variable at global scope. This occurs before main() and before any threads are created.
gg
"workaround" usually implies a problem. What is the problem with a pointer?
If what you want is for the instance to be in the static section, you can always do this:
This requires greedy initialization, but is thread safe.Code:class MyClass
{
private:
static MyClass m_gInst;
public:
static MyClass& GetInst()
{return MyClass::m_gInst;}
};
//Inside cpp
MyClass MyClass::m_gInst;
*OR*
[EDIT]ON SECOND THOUGHT: DON'T DO THIS. See Codeplug's post for why.[/EDIT]
Another alternative to to declare a table to house the instance of your class, and merely construct it on demand. This requires an external static/extern though, given the use of the "sizeof" operator. It also needs a helper "instanciated" bool:
Note that this is just as thread-unsafe as any other classic singleton though.Code:class MyClassHelper;
class MyClass
{
private:
static bool instanciated;
public:
static MyClass& GetInst();
};
class MyClassHelper
{
friend class MyClass;
static char m_gInst[sizeof(MyClass)];
};
MyClass& MyClass::GetInst()
{
if(MyClass::instanciated == false)
{
new (MyClassHelper::m_gInst) MyClass;
MyClass::instanciated = true;
}
return * reinterpret_cast<MyClass*>(MyClassHelper::m_gInst);
}
//in cpp
bool MyClass::instanciated = false;
char MyClassHelper::m_gInst[sizeof(MyClass)];
>> static char m_gInst[sizeof(MyClass)];
This does not guarantee proper alignment. http://www.gotw.ca/gotw/028.htm
gg
as a side note, you can use boost optional ( or in some situations boost variant ) to defer construction of stack variables without worrying of alignment issues:
Code:boost::optional<MyClass> x;
// ...
if( !x ) x = boost::in_place( <<MyClass's ctor args>> );
thanks for your help guys.