I have done little work in multi-threaded environments. So, I need to know whether below class's getInstance function is thread-safe or not. Here is singleton class :
//Singleton class
class S {
// intentionally avoided pointer
static S singleObject;
// Private constructor
s ();
s (S &);
s& operator= (const s&);
public:
// return reference of static object
s& getInstance ()
{
return singleObject;
}
/* Normally with static pointer instance, getInstnace look like as
s& getInstace ()
{
// trying to avoid multiple copies of singleObject
lock_mutex ()
if (singleObject == null)
singleObjecct = new S();
unlock_mutex ();
return *singleObject;
}
*/
};
S S::singleObject;
In getInstance function (un-commented), static object's reference is returned. Does it requires thread-safe mechanism?
In second getInstance (commented), we create the object if singleObject is null. So, it requires a locking mechanism and needs to be synchronized, right?
In getInstance function (un-commented), static object's reference is returned. Does it requires thread-safe mechanism?
As long as you don't access it outside the lifetime of the main function, or modify it when other threads might have unsynchronised access, then it's safe to access from any thread.
If you do access before main starts or after it ends (e.g. from the constructor or destructor of another static object), then there is a danger that it won't have been initialised, or will already have been destroyed, at that point. That is the motivation for "lazy initialisation" such as your second version.
In second getInstance (commented), we create the object if singleObject is null. So, it requires a locking mechanism and needs to be synchronized, right?
Yes, that requires a locking mechanism. For compilers that support the C++11 (or similar) threading model, a simpler way to get lazy initialisation like this is to use a function-static variable, which will be initialised in a thread-safe way the first time it comes into scope:
S& getInstance ()
{
static S singleObject;
return singleObject;
}
This will also avoid the memory leak of your version, but introduces a danger that it might be destroyed before other static objects; therefore, it's not safe to access from a static object's destructor.
In general, static objects in C++ are a minefield of such deathtraps (whether or not you try to wrap them up in some kind of singleton anti-pattern) and are best avoided.
In C++11 you can place static instance inside a static function:
class S
{
private:
S();
S(S const&);
S& operator=(S const&);
public:
static S& getInstance ()
{
static S singleObject;
return singleObject;
}
};
According to paragraph 6.7.4 of the Standard:
The zero-initialization (8.5) of all block-scope variables with static
storage duration (3.7.1) or thread storage duration (3.7.2) is
performed before any other initialization takes place. Constant
initialization (3.6.2) of a block-scope entity with static storage
duration, if applicable, is performed before its block is first
entered. An implementation is permitted to perform early
initialization of other block-scope variables with static or thread
storage duration under the same conditions that an implementation is
permitted to statically initialize a variable with static or thread
storage duration in namespace scope (3.6.2). Otherwise such a variable
is initialized the first time control passes through its declaration;
such a variable is considered initialized upon the completion of its
initialization. If the initialization exits by throwing an exception,
the initialization is not complete, so it will be tried again the next
time control enters the declaration. If control enters the declaration
concurrently while the variable is being initialized, the concurrent
execution shall wait for completion of the initialization. If
control re-enters the declaration recursively while the variable is
being initialized, the behavior is undefined.
Unless you declare getInstance as static you won't be able to call it. This mistake has propagated almost to all replies. Other than this, I can't add anything better to all the answers.
IIRC this is better for more than this reason. It won't initialize (thread safely) until getInstance is called.
-edit- I remember some reasons now. You can't get access unless that method is called. You can call this in other class constructors and wont need to worry if S has been initialized or no. As in the other class may be constructed first in which case a crash or undefined behavior occurs.
//Singleton class
class S {
// intentionally avoided pointer
// Private constructor
s ();
s (S &);
s& operator= (const s&);
public:
// return reference of static object
s& getInstance ()
{
static S singleObject;
return singleObject;
}
};
Related
I'm using Visual Studio 2013, which doesn't have "magic statics" feature implemented yet, so local static variables initialization isn't yet thread-safe. So, instead of
Foo& GetInstance()
{
static Foo foo;
return foo;
}
I do something like this:
std::unique_ptr<Foo> gp_foo;
std::once_flag g_flag;
Foo& GetInstance()
{
std::call_once(g_flag, [](){ gp_foo = std::make_unique<Foo>(); });
return *gp_foo;
}
But I don't like the idea of having gp_foo and g_flag global variables (first, problem with the order of initialization of static variables in different translation units; second, I would like to initialize variables only when we need them, i.e. after first call to GetInstance()), so I implemented the following:
Foo& GetInstance()
{
// I replaced a smart pointer
// with a raw one just to be more "safe"
// not sure such replacing is really needed
static Foo *p_foo = nullptr;
static std::once_flag flag;
std::call_once(flag, [](){ p_foo = new Foo; });
return *p_foo;
}
And it seems to work (at least it passes the tests), but I'm not sure it's thread-safe, because here we have the same potential problem with the initialization of static local variables p_foo and flag in multiple threads. Initialization of raw pointer with nullptr and initialization of std::once_flag seems more innocent than calling Foo's constructor, but I would like to know whether it is really safe.
So, are there any problems with the last code snippet?
By far the most stable approach to singleton object initialisation is the schwartz_counter. It's how std::cin, cout etc are implemented and how they always work, regardless of initialisation order of global objects.
It works in all versions of c++.
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
If Foo& GetInstance() is only part of the same compilation unit then the initialization order is defined hence it is thread safe.
However, if above is not the case and multiple compilation units are referencing that then the initialization order would depend on the order of the calls to Foo& GetInstance() and if multiple threads are involved then the order is undefined hence not thread safe.
Worth checking:
Static variables initialisation
order
zero initialization and static initialization of local scope static variable
Your last code snippet is fine from a thread-safe initialization point of view.
However, it is not clear how are you going to use the Foo object in threads calling GetInstance.
Since you are returning a reference to a non-const object, I suppose threads may modify the Foo object.
Keep in mind that you need additional synchronization for this (eg. a mutex)
If the Foo object is fully initialized by its constructor and threads calling GetInstance will only read from the object, there is no problem but I would suggest to return const Foo &
Assuming I have the following code
Something.hpp
#pragma once
class Something {
public:
static Something& get();
private:
Something();
};
Something.cpp
#include "Something.hpp"
#include <iostream>
using namespace std;
Something& Something::get() {
static Something something;
return something;
}
Something::Something() {
cout << "Something()" << endl;
}
main.cpp
#include <iostream>
using namespace std;
struct SomethingElse {
~SomethingElse() {
Something::get();
cout << "~SomethingElse" << endl;
}
};
void func() {
static SomethingElse something_else;
// do something with something_else
}
int main() {
func();
return 0;
}
Can more than one instance of the Something object ever be created? Does the standard say anything about serializing the destruction of static objects?
Note I am aware the the destruction of file level static variables is undefined when across different translation units, I wanted to know what happens in the case of function scoped static variables (which have the double-checked locking pattern built into the C++ runtime) For the same translation unit case with file level static variables, its easy for the compiler to ensure serialization with construction and destruction based on how the variables are laid out in the code (static), but what happens when the variables are dynamically lazily created when the functions are called?
Note What about for primitive variables? Can we expect them to contain their values till program end? Since they don't need to be destroyed.
Edit
Found this on cppreference.com (http://en.cppreference.com/w/cpp/utility/program/exit)
If the completion of the constructor or dynamic initialization for thread-local or static object A was sequenced-before thread-local or static object B, the completion of the destruction of B is sequenced-before the start of the destruction of A
If this is true then destruction for every static object is serialized? But I also found this
https://isocpp.org/wiki/faq/ctors#construct-on-first-use-v2 which contradicts the standard
The order of construction and destruction of static (and global non-static) objects is well-defined in the C++ specification, for a single translation unit!
If you have multiple translation unit (multiple source files) then the order of construction/destruction between the TUs is not defined.
So the code you show can have undefined behavior.
[stmt.dcl] ¶4
Dynamic initialization of a block-scope variable with static storage duration or thread storage duration is performed the first time control passes through its declaration.
[basic.start.term] ¶1
If the completion of the constructor or dynamic initialization of an object with static storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.
¶2
If a function contains a block-scope object of static or thread storage duration that has been destroyed and the function is called during the destruction of an object with static or thread storage duration, the program has undefined behaviour if the flow of control passes through the definition of the previously destroyed block-scope object.
It is in the destructor of SomethingElse that we risk invoking this undefined behaviour:
SomethingElse::~SomethingElse() {
Something::get();
}
If there is an instance of SomethingElse with static storage duration, then there are four possibilities:
The single instance of Something was constructed before the SomethingElse. Its destruction will happen after the SomethingElse, so the behaviour is well defined.
The single instance of Something was constructed after the SomethingElse. Its destruction will have happened before the SomethingElse, so the behaviour is undefined as described above.
The single instance of Something was constructed in a different thread without being synchronized with respect to the construction of the SomethingElse. The destructions may happen concurrently, so the behaviour is undefined.
No instance of Something was yet constructed (i.e. this is the first call to Something::get). In this case, the program calls for the construction of a Something after the SomethingElse, which means the destruction of the Something must happen before the SomethingElse, but since the destruction of the SomethingElse has already commenced, this is a contradiction, and the behaviour is undefined. (Technically, there is a cycle in the "sequenced before" relation.)
Static locals are guaranteed to be instantiated at first use by the C++ standard. However, I'm wondering what happens if I access a static local object while it is beeing constructed. I assume that this is UB.
But what are the best practices to avoid this in the following situation?
A problem situation
The Meyers Singleton pattern uses a static local in a static getInstance() method to construct the object on the first use. Now if the constructor (directly or indireclty) calls getInstance() again, we face
a situation where the static initialization is not yet completed. Here is a minimal example, that illustrates the problem situation:
class StaticLocal {
private:
StaticLocal() {
// Indirectly calls getInstance()
parseConfig();
}
StaticLocal(const StaticLocal&) = delete;
StaticLocal &operator=(const StaticLocal &) = delete;
void parseConfig() {
int d = StaticLocal::getInstance()->getData();
}
int getData() {
return 1;
}
public:
static StaticLocal *getInstance() {
static StaticLocal inst_;
return &inst_;
}
void doIt() {};
};
int main()
{
StaticLocal::getInstance()->doIt();
return 0;
}
In VS2010, this works without problems, but VS2015 deadlocks.
For this simple, reduced situation, the obvious solution is to direclty call getData(), without calling getInstance() again. However, in more complex scenarios (as my actual situation), this solution is not feasible.
Attempting a solution
If we change the getInstance() method to work on a static local pointer like this (and thus abandon the Meyers Singleton pattern):
static StaticLocal *getInstance() {
static StaticLocal *inst_ = nullptr;
if (!inst_) inst_ = new StaticLocal;
return inst_;
}
It is clear that we get an endless recursion. inst_ is nullptr on the first invokation, so we call the constructor with new StaticLocal. At this point, inst_ is still nullptr as it will only get assigned when
the constructor finishes. However, the constructor will call getInstance() again, finding a nullptr in inst_, and thus call the constructor again. And again, and again, ...
A possible solution is to move the constructor's body into the getInstance():
StaticLocal() { /* do nothing */ }
static StaticLocal *getInstance() {
static StaticLocal *inst_ = nullptr;
if (!inst_) {
inst_ = new StaticLocal;
inst_->parseConfig();
}
return inst_;
}
This will work. However, I'm not happy with this situation, as a constructor should, well, construct a complete object. It is debateable if this situation can be made an exception, as it is a singleton. However, I dislike it.
But what's more, what if the class has a non-trivial destructor?
~StaticLocal() { /* Important Cleanup */ }
In the above situation, the destructor is never called. We loose RAII and thus one important distinguishing feature of C++! We are in a world like Java or C#...
So we could wrap our singleton in some sort of smart pointer:
static StaticLocal *getInstance() {
static std::unique_ptr<StaticLocal> inst_;
if (!inst_) {
inst_.reset(new StaticLocal);
inst_->parseConfig();
}
return inst_.get();
}
This will correctly call the destructor on program exit. But it forces us to make the destructor public.
At this point, I feel I'm doing the compiler's job...
Back to the original question
Is this situation really undefined behaviour? Or is it a compiler bug in VS2015?
What is the best solution to such a situation, prefably without dropping a full constructor, and RAII?
This leads to undefined behaviour by c++ 11 standard. The relevant section is 6.7:
If control enters the declaration concurrently while the variable is
being initialized, the concurrent execution shall wait for completion
of the initialization. If control re-enters the declaration
recursively while the variable is being initialized, the behavior is
undefined.
The example from the standard is bellow:
int foo(int i) {
static int s = foo(2*i); // recursive call - undefined
return i+1;
}
You are facing the deadlock since MSVC inserts mutex lock/unlock to make static variable initialization thread safe. Once you call it recursively, you are locking the same mutex two times in the same thread, what leads to dead lock.
This is how static initialization is implemented internally in llvm compiler.
The best solution IMO is to do not use singletons at all. Significant group of developers tend to think that singleton is anti-pattern. The issues like you mentioned is really hard to debug, because it occurs before main. Because order of globals initialization is undefined. Also, multiple translation units might be involved, so compiler won't catch this types of errors. So, when I faced the same problem in production code, I was obliged to remove all of the singletons.
If you still think that singleton is the right way to go, then you need to re-structurize your code somehow when your singleton object owns (holds them as members, for example) all the classes that calls GetInstance during the singleton initialization. Think of your classes like ownership tree, where the singleton is the root. Pass reference to parent, when you create a child, if child needs it.
The problem is that inside the class, you should be using "this" instead of calling getInstance, in particular:
void parseConfig() {
int d = StaticLocal::getInstance()->getData();
}
Should simply be:
void parseConfig() {
int d = getData();
}
The object is a singleton because the constructor is private and thus the user cannot construct an arbitrary number of objects. It's bad design to write the whole class assuming there will be only one instance of the object ever. At some point somebody may stretch the concept of a singleton like this:
static StaticLocal *getInstance(int idx) {
static StaticLocal inst_[3];
if (idx < 0 || idx >= 3)
throw // some error;
return &inst_[idx];
}
When that happens, it's much easier to update the code if there aren't calls to getInstance() throughout the class.
Why do changes like this happen? Imagine you were writing a class 20 years ago to represent the CPU. Of course there will only ever be one CPU in the system, so you make it a singleton. Then, suddenly, multi-core systems become commonplace. You still want only as many instances of the CPU class as there are cores in the system, but you won't know until the program is run how many cores are actually on a given system.
Moral of the story: Using the this pointer not only avoids recursively calling getInstance(), but future proofs your code as well.
Actually this code in its current form is stuck into 3-way infinite recursion. Hence it will never work.
getInstance() --> StaticLocal()
^ |
| |
----parseConfig() <---
To let it work, anyone of the above 3 methods has to compromise and come out of the vicious circle. You judged it right, parseConfig() is the best candidate.
Let's assume that all the recursive content of constructor is put into parseConfig() and non-recursive contents are retained in constructor. Then you may do following (only relevant code):
static StaticLocal *s_inst_ /* = nullptr */; // <--- introduce a pointer
public:
static StaticLocal *getInstance() {
if(s_inst_ == nullptr)
{
static StaticLocal inst_; // <--- RAII
s_inst_ = &inst_; // <--- never `delete s_inst_`!
s_inst_->parseConfig(); // <--- moved from constructor to here
}
return s_inst_;
}
This works fine.
One straight forward way of solving this is to separate the responsibilities, in this case "whatever StaticLocal is supposed to do" and "reading the configuration data"
class StaticLocal;
class StaticLocalData
{
private:
friend StaticLocal;
StaticLocalData()
{
}
StaticLocalData(const StaticLocalData&) = delete;
StaticLocalData& operator=(const StaticLocalData&) = delete;
int getData()
{
return 1;
}
public:
static StaticLocalData* getInstance()
{
static StaticLocalData inst_;
return &inst_;
}
};
class StaticLocal
{
private:
StaticLocal()
{
// Indirectly calls getInstance()
parseConfig();
}
StaticLocal(const StaticLocal&) = delete;
StaticLocal& operator=(const StaticLocal&) = delete;
void parseConfig()
{
int d = StaticLocalData::getInstance()->getData();
}
public:
static StaticLocal* getInstance()
{
static StaticLocal inst_;
return &inst_;
}
void doIt(){};
};
int main()
{
StaticLocal::getInstance()->doIt();
return 0;
}
This way, StaticLocal does not call itself, the circle is broken.
Also, you have cleaner classes. If you move the implementation of StaticLocal into a separate compile unit, users of static local won't even know that the StaticLocalData thingy exists.
There is a good chance that you will find that you do not need the functionality of StaticLocalData to be wrapped into a Singleton.
All versions of the C++ standard have a paragraph that makes this undefined behaviour. In C++98, Section 6.7 para 4.
An implementation is permitted to perform early initialization of
other local objects with static storage duration under the same
conditions that an implementation is permitted to statically
initialize an object with static storage duration in namespace scope
(3.6.2). Otherwise such an object is initialized the first time
control passes through its declaration; such an object is considered
initialized upon the completion of its initialization. If the
initialization exits by throwing an exception, the initialization is
not complete, so it will be tried again the next time control enters
the declaration. If control reenters the declaration (recursively)
while the object is being initialized, the behavior is undefined.
All subsequent standards have essentially the same paragraph (only differences are inconsequential - such as section numbering for cross-referencing, etc).
What you have done is implement the constructor of your singleton so it calls the function which constructs it. getInstance() creates the object, the constructor (indirectly) calls getInstance(). Hence it runs afoul of the last sentence in the quote above, and introduces undefined behaviour.
The solution, as with anything recursive, is to either reimplement so recursion does not occur, or to prevent interference between the first call and any recursive calls.
There are three ways to achieve this.
The first, which you have said you don't want, is to construct an object and then parse data to initialise it (two-stage construction).
The second is to parse the data first, and only construct the object if the parsed data is valid (i.e. suitable for use in constructing the object).
The third is for the constructor to handle the parsing (which you are trying to do) but, if parsed data is invalid, to force the constructor to fail (which your code does not do).
An example of the third is to leave the getInstance() alone, and restructure the constructor so it never calls getInstance().
static StaticLocalData* getInstance()
{
static StaticLocalData inst_;
return &inst_;
}
StaticLocalData::StaticLocalData()
{
parseConfig();
}
void StaticLocalData::parseConfig()
{
int data = getData(); // data can be any type you like
if (IsValid(data))
{
// this function is called from constructor so simply initialise
// members of the current object using data
}
else
{
// okay, we're in the process of constructing our object, but
// the data is invalid. The constructor needs to fail
throw std::invalid_argument("Construction of static local data failed");
}
}
In the above, IsValid() represents a function or expression that checks if the parsed data is valid.
This approach actually exploits the second last sentences in the paragraph I quoted above from the standard. It has the effect of ensuring that calling staticLocal::getInstance() repeatedly will keep resulting in an exception until the parsing succeeds. Once the parsing has succeeded, the object will exist, and no further attempt will be made to it (it's address will simply be returned instead).
If the caller does not catch the exception, the effect is simple - the program will terminate(). If the caller does catch the exception, it should not try to use the pointer.
try
{
StaticLocal *thing = StaticLocal::getInstance();
// code using thing here will never be reached if an exception is thrown
}
catch (std::invalid_argument &e)
{
// thing does not exist here, so can't be used
// Worry about recovery, not trying to use thing
}
So, yes, your approach introduces undefined behaviour. But same part of the standard that makes the behaviour undefined also provides the basis for a solution.
In terms of dtor, I think you don't have to worry about it. Once you define it, then it will be automatically called after main() exits.
see How to implement multithread safe singleton in C++11 without using <mutex>
singleton declaration in c++11 is thread safe by standard. In VS2015 it may be implemented by mutex.
So, you last solution is fully applicable
StaticLocal() { /* do nothing */ }
static StaticLocal *getInstance() {
static StaticLocal inst_;
std::call_once(once_flag, [&inst_]() {inst_.parseConfig(); return &inst_;});
return &inst_;
}
about destructor: you can register you singleton destructor by using
int atexit(void (*function)(void));. This applied in Linux and may be exist in Win too, as function from standard library.
Thanks in advance!
Referring to Effective c++ item 4, Scott Meyers said all static variable/instance will be destroyed once main() exit. Here, we assume the singleton is only used in main().
Indeed, we know that if we use both two following forms of singleton, the instance will be destroyed automatically once the main() exit. But I want to distinguish two reasons below, which one is the direct reason to free the singleton? BTW, what is the difference between this two forms?
Reason:
normal instance will be destroyed once main() exit. (Not related to static)
all static variable/instance will be destroyed once main() exit.
case 1:
//Singleton.h
class Singleton
{
private:
Singleton();
~Singleton();
public:
Singleton& Instance()
{
Return instance_;
}
static Singleton instance_;
};
//Singleton.c
Singleton Singleton::instance_
Instance destruction step:
Referring to Effective c++ item 4, static instance_ will be free by compiler.
This is reason 2.
case 2:
//Singleton.h
class Singleton
{
private:
Singleton();
~Singleton();
public:
Singleton& Instance()
{
static Singleton instance_;
Return instance_;
}
};
Instance destruction step:
The singleton 's destructor is called once program exit.
Then the destructor will free all the member, but no member inside class. This is reason 1.
Then the compiler will free all the static variable/instance, including instance_, this is not the job of class destructor. This is reason 2.
From the C++11 Standard:
3.6.3 Termination
1 Destructors (12.4) for initialized objects (that is, objects whose lifetime (3.8) has begun) with static storage duration are called as a result of returning from main and as a result of calling std::exit (18.5).
In both case, the singleton objects are of static storage duration.
In the first case, the object is always initialized. The destructor of the object will be always called at termination time.
In the second case, the object will be initialized only if Singleton::Instance() is called at least once. Otherwise the object will remain uninitialized. The destructor of the object won't be called if the object is not initialized. If the object is initialized, the destructor will be called at termination time.
class Singleton
{
private:
static Singleton s;
Singleton(){}
public:
static Singleton *getInstance()
{
return &s;
}
};
Singleton Singleton::s;
Is this a valid singleton class?
class Singleton
{
private:
static Singleton *m_instance;
Singleton(){}
public:
static Singleton *getInstance()
{
return m_instance;
}
};
Singleton * Singleton::m_instance = new Singleton;
.
class Singleton
{
private:
static Singleton *m_instance;
Singleton(){}
public:
static Singleton *getInstance()
{
if(m_instance == NULL)
{
lock();
if(m_instance == NULL)
m_instance = new Singleton;
unlock();
}
return m_instance;
}
};
Singleton * Singleton::m_instance = NULL;
The three singleton classes above both are thread safe, but they are both prone to "static initialization order fiasco", am I right?
Is this a valid singleton class?
Now, after the edit the answer is yes, it is valid & it is also thread safe since all non-function-scope static variables are constructed before main(), while there is only one active thread.
C++ Standard n3337 § 3.6.2/1 § 3.6.2/2: Initialization of non-local variables
There are two broad classes of named non-local variables: those with
static storage duration (3.7.1) and those with thread storage duration
(3.7.2). Non-local variables with static storage duration are
initialized as a consequence of program initiation. Non-local
variables with thread storage duration are initialized as a
consequence of thread execution. Within each of these phases of initiation, initialization occurs as follows.
Variables with static storage duration (3.7.1) or thread storage
duration (3.7.2) shall be zero-initialized (8.5) before any other
initialization takes place. Constant initialization is performed:
— if each full-expression (including implicit conversions) that
appears in the initializer of a reference with static or thread
storage duration is a constant expression (5.19) and the reference is
bound to an lvalue designating an object with static storage duration
or to a temporary (see 12.2);
— if an object with static or thread storage duration is initialized
by a constructor call, if the constructor is a constexpr constructor,
if all constructor arguments are constant expressions (including
conversions), and if, after function invocation substitution (7.1.5),
every constructor call and full-expression in the mem-initializers and
in the brace-or-equal-initializers for non-static data members is a
constant expression;
— if an object with static or thread storage duration is not
initialized by a constructor call and if every full-expression that
appears in its initializer is a constant expression.
Together, zero-initialization and constant initialization are called
static initialization; all other initial- ization is dynamic
initialization. Static initialization shall be performed before any
dynamic initialization takes place. (...)
C++ Standard n3337 § 6.7/4: Declaration statement
The zero-initialization (8.5) of all block-scope variables with static
storage duration (3.7.1) or thread storage duration (3.7.2) is
performed before any other initialization takes place. Constant
initialization (3.6.2) of a block-scope entity with static storage
duration, if applicable, is performed before its block is first
entered. An implementation is permitted to perform early
initialization of other block-scope variables with static or thread
storage duration under the same conditions that an implementation is
permitted to statically initialize a variable with static or thread
storage duration in namespace scope. Otherwise such a variable is
initialized the first time control passes through its declaration;
such a variable is considered initialized upon the completion of its
initialization. If the initialization exits by throwing an exception,
the initialization is not complete, so it will be tried again the next
time control enters the declaration. If control enters the declaration
concurrently while the variable is being initialized, the concurrent
execution shall wait for completion of the initialization*). (...)
*):
The implementation must not introduce any deadlock around execution of
the initializer.
But it is still prone to static initialization order fiasco. The common way to write getInstance is:
Singleton& getInstance()
{
static Singleton instance;
return instance;
}
This way you can avoid this initialization problem.
Is this a thread-safe singleton class?
In C++11 above code is thread safe. In C++03 you can use
pthread_once
Besides this you should also prevent from copying and assignment:
Singleton( Singleton const&); // Don't Implement
void operator=( Singleton const&); // Don't implement
As far as I can tell, it's thread safe. But it's susceptible to static initialization order fiasco.
If an object tries to access Singleton in it's constructor and that object is constructed during program initialization and this code is in another compilation unit than Singleton, it may or may not crash because Singleton::s may or may not have been initialized yet (because the order of initialization of static objects across compilation units is undefined). Here is an example:
// in another compilation unit, far far away
struct Foo {
Foo() {
Singleton::getInstance();
}
};
Foo foo;
That's the lazy initialised Singleton, yes. It is thread safe under C++11.