I recently came across the Nifty Counter Idiom. My understanding is that this is used to implement globals in the standard library like cout, cerr, etc. Since the experts have chosen it, I assume that it's a very strong technique.
I'm trying to understand what the advantage is over using something more like a Meyer Singleton.
For example, one could just have, in a header file:
inline Stream& getStream() { static Stream s; return s; }
static Stream& stream = getStream();
The advantage is you don't have to worry about reference counting, or placement new, or having two classes, i.e. the code is much simpler. Since it's not done this way, I'm sure there's a reason:
Is this not guaranteed to have a single global object across shared and static libraries? It seems like the ODR should guarantee that there can only be one static variable.
Is there some kind of performance cost? It seems like in both my code and the Nifty Counter, you are following one reference to get to the object.
Is there some situations where the reference counting is actually useful? It seems like it will still just lead to the object being constructed if the header is included, and destroyed at program end, like the Meyer Singleton.
Does the answer involve dlopen'ing something manually? I don't have too much experience with that.
Edit: I was prompted to write the following bit of code while reading Yakk's answer, I add it to the original question as a quick demo. It's a very minimal example that shows how using the Meyer Singleton + a global reference leads to initialization before main: http://coliru.stacked-crooked.com/a/a7f0c8f33ba42b7f.
The static local/Meyer's singleton + static global reference (your solution) is nearly equivalent to the nifty counter.
The differences are as follows:
No .cpp file is required in your solution.
Technically the static Steam& exists in every compilation unit; the object being referred to does not. As there is no way to detect this in the current version of C++, under as-if this goes away. But some implementations might actually create that reference instead of eliding it.
Someone could call getStream() prior to the static Stream& being created; this would cause difficulty in destruction order (with the stream being destroyed later than expected). This can be avoided by making that against the rules.
The standard is mandated to make creating the static Stream local in the inline getStream thread safe. Detecting that this is not going to happen is challenging for the compiler, so some redundant thread-safety overhead may exist in your solution. The nifty counter does not support thread safety explicitly; this is considered safe as it runs at static initialization time, prior to when threads are expected.
The call to getStream() must occur in each and every compilation unit. Only if it is proven that it cannot do anything may it be optimized out, which is difficult. The nifty counter has a similar cost, but the operation may or may not be be simpler to optimize out or in runtime cost. (Determining this will require inspecting resulting assembly output on a variety of compilers)
"magic statics" (statics locals without race conditions) where introduced in C++11. There could be other issues prior to C++11 magic statics with your code; the only one I can think of is someone calling getStream() directly in another thread during static initialization, which (as mentioned above) should be banned in general.
Outside the realm of the standard, your version will automatically and magically create a new singleton in each dynamicly linked chunk of code (DLL, .so, etc). The nifty counter will only create the singleton in the cpp file. This may give the library writer tighter control over accidentally spawning new singletons; they can stick it into the dynamic library, instead of spawning duplicates.
Avoiding having more than one singleton is sometimes important.
Summarizing the answers and comments:
Let's compare 3 different options for a library, wishing to present a global Singleton, as a variable or via a getter function:
Option 1 - the nifty counter pattern, allowing the use of a global variable that is:
assured to be created once
assured to be created before the first usage
assured to be created once across all shared objects that are dynamically linked with the library creating this global variable.
Option 2 - the Meyers singleton pattern with a reference variable (as presented in the question):
assured to be created once
assured to be created before the first usage
However, it will create a copy of the singleton object in shared objects, even if all shared objects and the main are linked dynamically with the library. This is because the Singleton reference variable is declared static in a header file and must have its initialization ready at compile time wherever it is used, including in shared objects, during compile time, before meeting the program they will be loaded to.
Option 3 - the Meyers singleton pattern without a reference variable (calling a getter for retrieving the Singleton object):
assured to be created once
assured to be created before the first usage
assured to be created once across all shared objects that are dynamically linked with the library creating this Singleton.
However, in this option there is no global variable nor inline call, each call for retrieving the Singleton is a function call (that can be cached on the caller side).
This option would look like:
// libA .h
struct A {
A();
};
A& getA();
// some other header
A global_a2 = getA();
// main
int main() {
std::cerr << "main\n";
}
// libA .cpp - need to be dynamically linked! (same as libstdc++ is...)
// thus the below shall be created only once in the process
A& getA() {
static A a;
return a;
}
A::A() { std::cerr << "construct A\n"; }
All of your questions about utility / performance of Nifty Counter aka Schwartz Counter were basically answered by Maxim Egorushkin in this answer (but see also the comment threads).
Global variables in modern C++
The main issue is that there is a trade-off taking place. When you use Nifty Counter your program startup time is a bit slower (in large projects), since all these counters have to run before anything can happen. That doesn't happen in Meyer's singleton.
However, in the Meyer's singleton, every time you want to access the global object, you have to check if it's null, or, the compiler emits code that checks if the static variable was already constructed before any access is attempted. In the Nifty Counter, you have your pointer already and you just fire away, since you can assume the init happened at startup time.
So, Nifty Counter vs. Meyer's singleton is basically a trade-off between program startup time and run-time.
With the solution you have here, the global stream variable gets assigned at some point during static initialization, but it is unspecified when. Therefore the use of stream from other compilation units during static initialization may not work. Nifty counter is a way to guarantee that a global (e.g. std::cout) is usable even during static initialization.
#include <iostream>
struct use_std_out_in_ctor
{
use_std_out_in_ctor()
{
// std::cout guaranteed to be initialized even if this
// ctor runs during static initialization
std::cout << "Hello world" << std::endl;
}
};
use_std_out_in_ctor global; // causes ctor to run during static initialization
int main()
{
std::cout << "Did it print Hello world?" << std::endl;
}
Related
My specific question is that when implementing a singleton class in C++, is there any substantial differences between the two below codes regarding performance, side issues or something:
class singleton
{
// ...
static singleton& getInstance()
{
// allocating on heap
static singleton* pInstance = new singleton();
return *pInstance;
}
// ...
};
and this:
class singleton
{
// ...
static singleton& getInstance()
{
// using static variable
static singleton instance;
return instance;
}
// ...
};
(Note that dereferencing in the heap-based implementation should not affect performance, as AFAIK there is no extra machine-code generated for dereferencing. It's seems only a matter of syntax to distinguish from pointers.)
UPDATE:
I've got interesting answers and comments which I try to summarize them here. (Reading detailed answers is recommended for those interested.):
In the singleton using static local variable, the class destructor is automatically invoked at process termination, whereas in the dynamic allocation case, you have to manage object destruction someway at sometime, e.g. by using smart pointers:
static singleton& getInstance() {
static std::auto_ptr<singleton> instance (new singleton());
return *instance.get();
}
The singleton using dynamic allocation is "lazier" than the static singleton variable, as in the later case, the required memory for the singleton object is (always?) reserved at process start-up (as part of the whole memory required for loading program) and only calling of the singleton constructor is deferred to getInstance() call-time. This may matter when sizeof(singleton) is large.
Both are thread-safe in C++11. But with earlier versions of C++, it's implementation-specific.
The dynamic allocation case uses one level of indirection to access the singleton object, whereas in the static singleton object case, direct address of the object is determined and hard-coded at compile-time.
P.S.: I have corrected the terminology I'd used in the original posting according to the #TonyD's answer.
the new version obviously needs to allocate memory at run-time, whereas the non-pointer version has the memory allocated at compile time (but both need to do the same construction)
the new version won't invoke the object's destructor at program termination, but the non-new version will: you could use a smart pointer to correct this
you need to be careful that some static/namespace-scope object's destructors don't invoke your singleton after its static local instance's destructor has run... if you're concerned about this, you should perhaps read a bit more about Singleton lifetimes and approaches to managing them. Andrei Alexandrescu's Modern C++ Design has a very readable treatment.
under C++03, it's implementation-defined whether either will be thread safe. (I believe GCC tends to be, whilst Visual Studio tends not -comments to confirm/correct appreciated.)
under C++11, it's safe: 6.7.4 "If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization." (sans recursion).
Discussion re compile-time versus run-time allocation & initialisation
From the way you've worded your summary and a few comments, I suspect you're not completely understanding a subtle aspect of the allocation and initialisation of static variables....
Say your program has 3 local static 32-bit ints - a, b and c - in different functions: the compiler's likely to compile a binary that tells the OS loader to leave 3x32-bits = 12 bytes of memory for those statics. The compiler decides what offsets each of those variables is at: it may put a at offset 1000 hex in the data segment, b at 1004, and c at 1008. When the program executes, the OS loader doesn't need to allocate memory for each separately - all it knows about is the total of 12 bytes, which it may or may not have been asked specifically to 0-initialise, but it may want to do anyway to ensure the process can't see left over memory content from other users' programs. The machine code instructions in the program will typically hard-code the offsets 1000, 1004, 1008 for accesses to a, b and c - so no allocation of those addresses is needed at run-time.
Dynamic memory allocation is different in that the pointers (say p_a, p_b, p_c) will be given addresses at compile time as just described, but additionally:
the pointed-to memory (each of a, b and c) has to be found at run-time (typically when the static function first executes but the compiler's allowed to do it earlier as per my comment on the other answer), and
if there's too little memory currently given to the process by the Operating System for the dynamic allocation to succeed, then the program library will ask the OS for more memory (e.g. using sbreak()) - which the OS will typically wipe out for security reasons
the dynamic addresses allocated for each of a, b and c have to be copied back into the pointers p_a, p_b and p_c.
This dynamic approach is clearly more convoluted.
The main difference is that using a local static the object will be destroyed when closing the program, instead heap-allocated objects will just be abandoned without being destroyed.
Note that in C++ if you declare a static variable inside a function it will be initialized the first time you enter the scope, not at program start (like it happens instead for global static duration variables).
In general over the years I switched from using lazy initialization to explicit controlled initialization because program startup and shutdown are delicate phases and quite difficult to debug. If your class is not doing anything complex and just cannot fail (e.g. it's just a registry) then even lazy initialization is fine... otherwise being in control will save you quite a lot of problems.
A program that crashes before entering the first instruction of main or after executing last instruction of main is harder to debug.
Another problem of using lazy construction of singletons is that if your code is multithread you've to pay attention to the risk of having concurrent threads initializing the singleton at the same time. Doing initialization and shutdown in a single thread context is simpler.
The possible races during initialization of function-level static instances in multithreaded code has been resolved since C++11, when the language added official multithreading support: for normal cases proper synchronization guards are automatically added by the compiler so this is not a concern in C++11 or later code. However if initialization of a static in function a calls function b and vice-versa you can risk a deadlock if the two functions are called the first time at the same time by different threads (this is not an issue only if the compiler uses a single mutex for all statics). Note also that calling the function that contains a static object from within the initialization code of the static object recursively is not permitted.
What are disadvantages of using static variables like in following code:
namespace XXX
{
static int i;
class YYY
{
static m_i;
};
}
Is using static variables only in .cpp (so they are invisible to other code) file OK?
It totally depends on what you need to do. There is no general aversion to using statics. Note that statics are essentially the singleton pattern, so all the pros/cons about singletons apply.
In terms of threads you have to pay attention since the same instance could be access by multiple threads at the same time. If you only need to read the data then you shouldn't have any problems. If you need to modify the data you have to worry about synchronization.
For code reuse and testing singeltons can often pose a problem. You can't for example recreate the object in a test, or have multiple run in parallel. In general when I use singletons/statics I try to ensure that one instance of the entire life of all tests, parallel executions, etc. is totally okay.
Invisible statics as you call them (visible only to the compilation unit) are a good idea. This helps you maintain synchronization between threads and manage them correctly. If they have global visibility then they can be modified at any time (well private variables can't, so they are also good).
Also note that atomic variables can be safely read/written from various threads. For simple counters this is often a good solution: using atomic increment. In C++0x you can use "atomic", previously use your OS/compiler function that does it. As with the singleton pattern, you can easily design classes where each function is synchronized so the singleton user doesn't have to worry about it. That is to say, statics aren't inherently thread-safe even when doing writing.
Various things allowed by C++ represent choices and compromises in software design. There is nothing inherently, absolutely evil about any of them (except perhaps throw specifications, which Prof. Stroustrop deems a broken facility ;-P).
Whether this particular code is a good choice in a particular situation depends on many factors. For example:
there'll only be one copy shared by the entire program
may be ideal, e.g. you want to have some program-wide modal state
terrible: code setting/using the value may find other code has modified it meanwhile (this gets increasingly likely as the program gets larger and more complex)
terrible: in multi-threaded code you must use locking and/or atomic operations to avoid data corruption and consequent erroneous behaviour and/or crashes
being static:
other translation units won't have access to it
it won't pollute the symbol table exposed by a good IDE etc.
In short, if you realise that namespaces and static just reduce identifier clashes, they've got all the other pros/cons associated with global variables....
Also you can have some problems with static class members while working with runtime shared libs. For example: if you have:
class A {
//...
static int staticInt;
//...
};
And you link this class to main executable AND to runtime shared lib, which is used by this executable (via dlopen) in several cases you can receive segmentation faults due to reinitialization of main executable's copy of static member by loaded shared lib. You can find more details concerning this issue here and there
For one it's not thread safe. You might want to consider the singleton pattern with some kind of locking to protect it.
One disadvantage you must be aware of is the so-called "static initialization order fiasco." Here is an example:
// foo.cpp
class foo {
public:
static bar m_bar;
};
bar foo::m_bar;
// baz.cpp
class baz {
public:
baz() {
/* some code */
foo::m_bar.someMethod();
}
};
baz g_baz; //TROUBLE!!
The C++ standard makes no guarantee about which will be initialized first of m_bar and g_baz. If you're lucky and m_bar gets initialized first, g_baz will be constructed without a hitch. If not, your program will likely segfault, or worse.
Replacing m_bar with a method returning a static pointer constructed on first use circumvents this problem (NB: it's still not thread-safe):
class foo {
public:
static bar &getBar() { if(!m_barinst) m_barinst = new bar; return *m_barinst; }
private:
static bar *m_barinst;
};
bar *foo::m_barinst = NULL;
Currently I'm using singleton pattern for certain global objects in my application (Qt application for Symbian environment). However, because of some problems (C++ checking singleton pointers) it looks like that I have to change the logic.
I have 3 classes (logger, settings and container for some temp data) that I need to access via multiple different objects. Currently they are all created using singleton pattern. The logger basically is just one public method Log() with some internal logic when the settings and container have multiple get/set methods with some additional logic (e.g. QFileSystemWatcher). In addition, logger and settings have some cross-reference (e.g. logger needs some settings and settings logs errors).
Currently everything is "working fine", but there is still some problems that should be taken care of and it seems like they are not easy to implement for the singletons (possible memory leaks/null pointers). Now I have two different ways to handle this:
Create global objects (e.g. extern Logger log;) and initialize them on application startup.
Create objects in my main object and pass them to the children as a reference.
How I have few questions related to these:
Case 1.
Is it better to use stack or heap?
I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?
I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?
Case 2.
Should the objects be created in stack or heap in my main object (e.g. Logger *log = new Logger() vs Logger log;)
Long reference chains do not look nice (e.g. if i have to pass the object over multiple childrens).
What about in children?
If I pass a pointer to the children like this (I don't want to copy it, just use the "reference"): Children(Logger *log) : m_Log(log) what happens when the children is deleted? Should I set the local pointer m_Log to NULL or?
If I use stack I'll send reference to the child (Children(Logger &log) : m_Log(log)) where m_Log is a reference variable (Logger& m_Log;) right?
What should I note in terms of Qt memory management in this case?
Case 3.
Continue with singleton and initialize singleton objects during the startup (that would solve the null pointers). Then the only problem would possible memory leaks. My implementation follows this example. Is there a possible memory leak when I'm accessing the class using. What about singleton destruction?
#define LOG Logger::Instance()->Log
Thanks for reading.
Summary in simple terms:
if you use global objects, prefer the singleton pattern as a lesser evil. Note that a singleton should have global access! Dan-O's solution is not really a singleton pattern and it defeats the power of singletons even though he suggests it's no different.
if you use global objects, use lazy construction to avoid initialization order problems (initialize them when they are first accessed).
if you use singletons, instead of making everything that needs to be globally acccessible a singleton, consider making one singleton (Application) which stores the other globally-accessible objects (Logger, Settings, etc.) but don't make these objects singletons.
if you use locals, consider #3 anyway to avoid having to pass so many things around your system.
[Edit] I made a mistake and misplaced the static in safe_static which Dan pointed out. Thanks to him for that. I was blind for a moment and didn't realize the mistake based on the questions he was asking which lead to a most awkward situation. I tried to explain the lazy construction (aka lazy loading) behavior of singletons and he did not follow that I made a mistake and I still didn't realize I made one until the next day. I'm not interested in argument, only providing the best advice, but I must suggest strongly against some of the advice, particularly this case:
#include "log.h"
// declare your logger class here in the cpp file:
class Logger
{
// ... your impl as a singleton
}
void Log( const char* data )
{
Logger.getInstance().DoRealLog( data );
}
If you are going to go with globally accessible objects like singletons, then at least avoid this! It may have appealing syntax for the client, but it goes against a lot of the issues that singletons try to mitigate. You want a publicly accessible singleton instance and if you create a Log function like this, you want to pass your singleton instance to it. There are many reasons for this, but here is just one scenario: you might want to create separate Logger singletons with a common interface (error logger vs. warning logger vs. user message logger, e.g.). This method does not allow the client to choose and make use of a common logging interface. It also forces the singleton instance to be retrieved each time you log something, which makes it so that if you ever decide to steer away from singletons, there will be that much more code to rewrite.
Create global objects (e.g. extern
Logger log;) and initialize them on
application startup.
Try to avoid this at all costs for user-defined types, at least. Giving the object external linkage means that your logger will be constructed prior to the main entry point, and if it depends on any other global data like it, there's no guarantee about initialization order (your Logger could be accessing uninitialized objects).
Instead, consider this approach where access is initialization:
Logger& safe_static()
{
static Logger logger;
return logger;
}
Or in your case:
// Logger::instance is a static method
Logger& Logger::instance()
{
static Logger logger;
return logger;
}
In this function, the logger will not be created until the safe_static method is called. If you apply this to all similar data, you don't have to worry about initialization order since initialization order will follow the access pattern.
Note that despite its name, it isn't uber safe. This is still prone to thread-related problems if two threads concurrently call safe_static for the first time at the same time. One way to avoid this is to call these methods at the beginning of your application so that the data is guaranteed to be initialized post startup.
Create objects in my main object and
pass them to the children as a
reference.
It might become cumbersome and increase code size significantly to pass multiple objects around this way. Consider consolidating those objects into a single aggregate which has all the contextual data necessary.
Is it better to use stack or heap?
From a general standpoint, if your data is small and can fit comfortably in the stack, the stack is generally preferable. Stack allocation/deallocation is super fast (just incrementing/decrementing a stack register) and doesn't have any problems with thread contention.
However, since you are asking this specifically with respect to global objects, the stack doesn't make much sense. Perhaps you're asking whether you should use the heap or the data segment. The latter is fine for many cases and doesn't suffer from memory leak problems.
I'm going to declare those objects in
some globals.h header using extern
keyword. Is it ok?
No. #see safe_static above.
I think in this case I have to remove that 2-way reference (settings
needs logger and vice versa.)?
It's always good to try to eliminate circular dependencies from your code, but if you can't, #see safe_static.
If I pass a pointer to the children
like this (I don't want to copy it,
just use the "reference"):
Children(Logger *log) : m_Log(log)
what happens when the children is
deleted? Should I set the local
pointer m_Log to NULL or?
There's no need to do this. I'm assuming the memory management for the logger is not dealt with in the child. If you want a more robust solution, you can use boost::shared_ptr and reference counting to manage the logger's lifetime.
If I use stack I'll send reference to
the child (Children(Logger &log) :
m_Log(log)) where m_Log is a reference
variable (Logger& m_Log;) right?
You can pass by reference regardless of whether you use the stack or heap. However, storing pointers as members over references has the benefit that the compiler can generate a meaningful assignment operator (if applicable) in cases where it's desired but you don't need to explicitly define one yourself.
Case 3. Continue with singleton and
initialize singleton objects during
the startup (that would solve the null
pointers). Then the only problem would
possible memory leaks. My
implementation follows this example.
Is there a possible memory leak when
I'm accessing the class using. What
about singleton destruction?
Use boost::scoped_ptr or just store your classes as static objects inside an accessor function, like in safe_static above.
I found the other answer to be a little misleading. Here is mine, hopefully the SO community will determine which answer is better:
Is it better to use the stack or the heap?
Assuming by "the stack" you meant as a global (and thus in the data segment), don't worry about it, do whichever is easier for you. Remember that if you allocate it on the heap you do have to call delete.
I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?
Why do you need to do that? The only classes that need access to the globals are the singletons themselves. The globals can even be static local variables, ala:
class c_Foo
{
static c_Foo& Instance()
{
static c_Foo g_foo; // static local variable will live for full life of the program, but cannot be accessed elsewhere, forcing others to use cFoo::Instance()
return g_foo;
}
};
If you don't want to use the static local then a private static member variable of type c_Foo (in my example) would be more appropriate than a straight global.
Remember, you want the lifetime of the class to be "global" (ie not destroyed until application exit), not the instance itself.
I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?
All of the externed globals would have to be forward declared, but as I said above you don't need this header file.
Should the objects be created in stack or heap in my main object (e.g. Logger *log = new Logger() vs Logger log;)
I can't really answer this, don't worry about it again.
Long reference chains do not look nice
(e.g. if i have to pass the object
over multiple childrens).
What about in children?
Great points, you have realized that this would be a huge pain in the butt. In the case of something like a logger it would be hellish to pass references to every module just so they could spit out logging info. More appropriate would be a single static "Log" function ala C, if your logger has useful state then make it a singleton that is only visible to your log function. You can declare and implement your entire logger class in the same .cpp file that you implement your log function in. Then nothing else will be aware of this special functionality.
Here is what I mean:
file: log.h
#ifndef LOG_H
#define LOG_H
void Log( const char* data ); // or QString or whatever you're passing to your logger
#endif//LOG_H
file: log.cpp
#include "log.h"
// declare your logger class here in the cpp file:
class Logger
{
// ... your impl as a singleton
}
void Log( const char* data )
{
Logger.getInstance().DoRealLog( data );
}
This is a fine logger interface, all the power of your singleton, limited fuss.
Is there a possible memory leak when I'm accessing the class using. What about singleton destruction?
There is a risk of double instantiation if you're lazily allocating the singleton on the heap in a multithreaded environment. This would cause surplus instances to leak.
There are somewhat similar risks if you use a static local: Link
In my opinion explicit construction when execution starts is the best option, but whether it is done in the data segment (with a static variable in a class or global variable) or the heap is very unlikely to matter in your case. If you do allocate it on the heap you should also delete it.
A friend of mine today asked me why should he prefer use of singleton over global static object?
The way I started it to explain was that the singleton can have state vs. static global object won't...but then I wasn't sure..because this in C++.. (I was coming from C#)
What are the advantages one over the other? (in C++)
Actually, in C++ preferred way is local static object.
Printer & thePrinter() {
static Printer printer;
return printer;
}
This is technically a singleton though, this function can even be a static method of a class. So it guaranties to be constructed before used unlike with global static objects, that can be created in any order, making it possible to fail unconsistently when one global object uses another, quite a common scenario.
What makes it better than common way of doing singletons with creating new instance by calling new is that object destructor will be called at the end of a program. It won't happen with dynamically allocated singleton.
Another positive side is there's no way to access singleton before it gets created, even from other static methods or from subclasses. Saves you some debugging time.
In C++, the order of instantiation of static objects in different compilation units is undefined. Thus it's possible for one global to reference another which is not constructed, blowing up your program. The singleton pattern removes this problem by tying construction to a static member function or free function.
There's a decent summary here.
A friend of mine today asked me why should he prefer use of singleton over global static object? The way I started it to explain was that the singleton can have state vs. static global object won't...but then I wasn't sure..because this in C++.. (I was coming from C#)
A static global object can have state in C# as well:
class myclass {
// can have state
// ...
public static myclass m = new myclass(); // globally accessible static instance, which can have state
}
What are the advantages one over the other? (in C++)
A singleton cripples your code, a global static instance does not.
There are countless questions on SO about the problems with singletons already. Here's one, and another, or another.
In short, a singleton gives you two things:
a globally accessible object, and
a guarantee that only one instance can be created.
If we want just the first point, we should create a globally accessible object.
And why would we ever want the second? We don't know in advance how our code may be used in the future, so why nail it down and remove what may be useful functionality? We're usually wrong when we predict that "I'll only need one instance". And there's a big difference between "I'll only need one instance" (correct answer is then to create one instance), and "the application can't under any circumstances run correctly if more than one instance is created. It will crash, format the user's harddrive and publish sensitive data on the internet" (the answer here is then: Most likely your app is broken, but if it isn't, then yes, a singleton is what you need)
Reason 1:
Singletons are easy to make so they are lazy build.
While you can do this with globals it take extra work by the developer. So by default globals are always initialized (apart from some special rules with namespaces).
So if your object is large and/or expensive to build you may not want to build it unless you really have to use it.
Reason 2:
Order of initialization (and destruction) problem.
GlobalRes& getGlobalRes()
{
static GlobalRes instance; // Lazily initialized.
return instance;
}
GlobalResTwo& getGlobalResTwo()
{
static GlobalResTwo instance; // Lazy again.
return instance;
}
// Order of destruction problem.
// The destructor of this object uses another global object so
// the order of destruction is important.
class GlobalResTwo
{
public:
GlobalResTwo()
{
getGlobalRes();
// At this point globalRes is fully initialized.
// Because it is fully initialized before this object it will be destroyed
// after this object is destroyed (Guaranteed)
}
~GlobalResTwo()
{
// It is safe to use globalRes because we know it will not be destroyed
// before this object.
getGlobalRes().doStuff();
}
};
Another benefit of the Singleton over the global static object is that because the constructor is private, there is a very clear, compiler enforced directive saying "There can only be one".
In comparison, with the global static object, there will be nothing stopping a developer writing code that creates an additional instance of this object.
The benefit of the extra constraint is that you have a guarantee as to how the object will be used.
Using Singleton("construct on first use") idiom, you can avoid static initialization order fiasco
In C++, there's not a huge amount of difference between the two in terms of actual usefulness. A global object can of course maintain its own state (possibly with other global variables, though I don't recommend it). If you're going to use a global or a singleton (and there are many reasons not to), the biggest reason to use a singleton over a global object is that with a singleton, you can have dynamic polymorphism by having several classes inheriting from a singleton base class.
OK, there are two reasons to go with a singleton really. One is the static order thing everyone's talking about.
The other is to prevent someone from doing something like this when using your code:
CoolThing blah;
gs_coolGlobalStaticThing = blah;
or, even worse:
gs_coolGlobalStaticThing = {};
The encapsulation aspect will protect your instance from idiots and malicious jerks.
Is there a way to implement a singleton object in C++ that is:
Lazily constructed in a thread safe manner (two threads might simultaneously be the first user of the singleton - it should still only be constructed once).
Doesn't rely on static variables being constructed beforehand (so the singleton object is itself safe to use during the construction of static variables).
(I don't know my C++ well enough, but is it the case that integral and constant static variables are initialized before any code is executed (ie, even before static constructors are executed - their values may already be "initialized" in the program image)? If so - perhaps this can be exploited to implement a singleton mutex - which can in turn be used to guard the creation of the real singleton..)
Excellent, it seems that I have a couple of good answers now (shame I can't mark 2 or 3 as being the answer). There appears to be two broad solutions:
Use static initialisation (as opposed to dynamic initialisation) of a POD static variable, and implementing my own mutex with that using the builtin atomic instructions. This was the type of solution I was hinting at in my question, and I believe I knew already.
Use some other library function like pthread_once or boost::call_once. These I certainly didn't know about - and am very grateful for the answers posted.
Basically, you're asking for synchronized creation of a singleton, without using any synchronization (previously-constructed variables). In general, no, this is not possible. You need something available for synchronization.
As for your other question, yes, static variables which can be statically initialized (i.e. no runtime code necessary) are guaranteed to be initialized before other code is executed. This makes it possible to use a statically-initialized mutex to synchronize creation of the singleton.
From the 2003 revision of the C++ standard:
Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place. Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit.
If you know that you will be using this singleton during the initialization of other static objects, I think you'll find that synchronization is a non-issue. To the best of my knowledge, all major compilers initialize static objects in a single thread, so thread-safety during static initialization. You can declare your singleton pointer to be NULL, and then check to see if it's been initialized before you use it.
However, this assumes that you know that you'll use this singleton during static initialization. This is also not guaranteed by the standard, so if you want to be completely safe, use a statically-initialized mutex.
Edit: Chris's suggestion to use an atomic compare-and-swap would certainly work. If portability is not an issue (and creating additional temporary singletons is not a problem), then it is a slightly lower overhead solution.
Unfortunately, Matt's answer features what's called double-checked locking which isn't supported by the C/C++ memory model. (It is supported by the Java 1.5 and later — and I think .NET — memory model.) This means that between the time when the pObj == NULL check takes place and when the lock (mutex) is acquired, pObj may have already been assigned on another thread. Thread switching happens whenever the OS wants it to, not between "lines" of a program (which have no meaning post-compilation in most languages).
Furthermore, as Matt acknowledges, he uses an int as a lock rather than an OS primitive. Don't do that. Proper locks require the use of memory barrier instructions, potentially cache-line flushes, and so on; use your operating system's primitives for locking. This is especially important because the primitives used can change between the individual CPU lines that your operating system runs on; what works on a CPU Foo might not work on CPU Foo2. Most operating systems either natively support POSIX threads (pthreads) or offer them as a wrapper for the OS threading package, so it's often best to illustrate examples using them.
If your operating system offers appropriate primitives, and if you absolutely need it for performance, instead of doing this type of locking/initialization you can use an atomic compare and swap operation to initialize a shared global variable. Essentially, what you write will look like this:
MySingleton *MySingleton::GetSingleton() {
if (pObj == NULL) {
// create a temporary instance of the singleton
MySingleton *temp = new MySingleton();
if (OSAtomicCompareAndSwapPtrBarrier(NULL, temp, &pObj) == false) {
// if the swap didn't take place, delete the temporary instance
delete temp;
}
}
return pObj;
}
This only works if it's safe to create multiple instances of your singleton (one per thread that happens to invoke GetSingleton() simultaneously), and then throw extras away. The OSAtomicCompareAndSwapPtrBarrier function provided on Mac OS X — most operating systems provide a similar primitive — checks whether pObj is NULL and only actually sets it to temp to it if it is. This uses hardware support to really, literally only perform the swap once and tell whether it happened.
Another facility to leverage if your OS offers it that's in between these two extremes is pthread_once. This lets you set up a function that's run only once - basically by doing all of the locking/barrier/etc. trickery for you - no matter how many times it's invoked or on how many threads it's invoked.
Here's a very simple lazily constructed singleton getter:
Singleton *Singleton::self() {
static Singleton instance;
return &instance;
}
This is lazy, and the next C++ standard (C++0x) requires it to be thread safe. In fact, I believe that at least g++ implements this in a thread safe manner. So if that's your target compiler or if you use a compiler which also implements this in a thread safe manner (maybe newer Visual Studio compilers do? I don't know), then this might be all you need.
Also see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2513.html on this topic.
You can't do it without any static variables, however if you are willing to tolerate one, you can use Boost.Thread for this purpose. Read the "one-time initialisation" section for more info.
Then in your singleton accessor function, use boost::call_once to construct the object, and return it.
For gcc, this is rather easy:
LazyType* GetMyLazyGlobal() {
static const LazyType* instance = new LazyType();
return instance;
}
GCC will make sure that the initialization is atomic. For VC++, this is not the case. :-(
One major issue with this mechanism is the lack of testability: if you need to reset the LazyType to a new one between tests, or want to change the LazyType* to a MockLazyType*, you won't be able to. Given this, it's usually best to use a static mutex + static pointer.
Also, possibly an aside: It's best to always avoid static non-POD types. (Pointers to PODs are OK.) The reasons for this are many: as you mention, initialization order isn't defined -- neither is the order in which destructors are called though. Because of this, programs will end up crashing when they try to exit; often not a big deal, but sometimes a showstopper when the profiler you are trying to use requires a clean exit.
While this question has already been answered, I think there are some other points to mention:
If you want lazy-instantiation of the singleton while using a pointer to a dynamically allocated instance, you'll have to make sure you clean it up at the right point.
You could use Matt's solution, but you'd need to use a proper mutex/critical section for locking, and by checking "pObj == NULL" both before and after the lock. Of course, pObj would also have to be static ;)
.
A mutex would be unnecessarily heavy in this case, you'd be better going with a critical section.
But as already stated, you can't guarantee threadsafe lazy-initialisation without using at least one synchronisation primitive.
Edit: Yup Derek, you're right. My bad. :)
You could use Matt's solution, but you'd need to use a proper mutex/critical section for locking, and by checking "pObj == NULL" both before and after the lock. Of course, pObj would also have to be static ;) . A mutex would be unnecessarily heavy in this case, you'd be better going with a critical section.
OJ, that doesn't work. As Chris pointed out, that's double-check locking, which is not guaranteed to work in the current C++ standard. See: C++ and the Perils of Double-Checked Locking
Edit: No problem, OJ. It's really nice in languages where it does work. I expect it will work in C++0x (though I'm not certain), because it's such a convenient idiom.
read on weak memory model. It can break double-checked locks and spinlocks. Intel is strong memory model (yet), so on Intel it's easier
carefully use "volatile" to avoid caching of parts the object in registers, otherwise you'll have initialized the object pointer, but not the object itself, and the other thread will crash
the order of static variables initialization versus shared code loading is sometimes not trivial. I've seen cases when the code to destruct an object was already unloaded, so the program crashed on exit
such objects are hard to destroy properly
In general singletons are hard to do right and hard to debug. It's better to avoid them altogether.
I suppose saying don't do this because it's not safe and will probably break more often than just initializing this stuff in main() isn't going to be that popular.
(And yes, I know that suggesting that means you shouldn't attempt to do interesting stuff in constructors of global objects. That's the point.)