66

I have been reading a lot about Singletons, when they should and shouldn't be used, and how to implement them safely. I am writing in C++11, and have come across the Meyer's lazy initialized implementation of a singleton, as seen in this question.

This implementation is:

static Singleton& instance() { static Singleton s; return s; } 

I understand how this is thread safe from other questions here on SO, but what I don't understand is how this is actually a singleton pattern. I have implemented singletons in other languages, and these always end up something like this example from Wikipedia:

public class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { } public static SingletonDemo getInstance() { if (instance == null) { synchronized (SingletonDemo .class){ if (instance == null) { instance = new SingletonDemo (); } } } return instance; } } 

When I look at this second example, it is very intuitive how this is a singleton, since the class holds a reference to one instance of itself, and only ever returns that instance. However, in the first example, I don't understand how this prevents there ever existing two instances of the object. So my questions are:

  1. How does the first implementation enforce a singleton pattern? I assume it has to do with the static keyword, but I am hoping that someone can explain to me in depth what is happening under the hood.
  2. Between these two implementation styles, is one preferable over the other? What are the pros and cons?

Thanks for any help,

7
  • 12
    The C++ code, the way you represent it, is not so much a singleton as it is a well-initialized global object. There's nothing stopping you from having another one of those (make another function), and that's fine. There's no point in forcing anyone to do anything. If you just want one, just make only one. Commented Jul 17, 2013 at 23:35
  • 3
    static Singleton s; means the first time the function is called this variable will be initialized and unlike non-static variables it will not be destroyed once the function ends. So when you call it again it will still exist so the only instruction that will be executed the 2nd (3rd, 4th, ...) time is return s. Commented Jul 17, 2013 at 23:35
  • 19
    I would imagine Singleton's constructor is private, so the only way to actually obtain an instance is via instance() function. Commented Jul 17, 2013 at 23:50
  • Singletons: just say no (also, your first example isn't a singleton in itself. You left out a bit of code.) Commented Jul 18, 2013 at 8:09
  • 1
    I have absolutely no idea why this would be closed as "primarily opinion-based". Ok, the second question might seem like it, but there may very well be (and actually are) objective reasons to prefer one implementation over the other and the first question, while lacking understanding of the static keyword, is a perfectly valid question, too. This cannot just be the singleton-haters screaming for blood. Seriously, I am one of those, too, but neither does this make this question invalid. +1 Commented Jul 18, 2013 at 9:41

2 Answers 2

68

This is a singleton because static storage duration for a function local means that only one instance of that local exists in the program.

Under the hood, this can very roughly be considered to be equivalent to the following C++98 (and might even be implemented vaguely like this by a compiler):

static bool __guard = false; static char __storage[sizeof(Singleton)]; // also align it Singleton& Instance() { if (!__guard ) { __guard = true; new (__storage) Singleton(); } return *reinterpret_cast<Singleton*>(__storage); } // called automatically when the process exits void __destruct() { if (__guard) reinterpret_cast<Singleton*>(__storage)->~Singleton(); } 

The thread safety bits make it get a bit more complicated, but it's essentially the same thing.

Looking at an actual implementation for C++11, there is a guard variable for each static (like the boolean above), which is also used for barriers and threads. Look at Clang's AMD64 output for:

Singleton& instance() { static Singleton instance; return instance; } 

The AMD64 assembly for instance from Ubuntu's Clang 3.0 on AMD64 at -O1 (courtesy of http://gcc.godbolt.org/ is:

instance(): # @instance() pushq %rbp movq %rsp, %rbp movb guard variable for instance()::instance(%rip), %al testb %al, %al jne .LBB0_3 movl guard variable for instance()::instance, %edi callq __cxa_guard_acquire testl %eax, %eax je .LBB0_3 movl instance()::instance, %edi callq Singleton::Singleton() movl guard variable for instance()::instance, %edi callq __cxa_guard_release .LBB0_3: movl instance()::instance, %eax popq %rbp ret 

You can see that it references a global guard to see if initialization is required, uses __cxa_guard_acquire, tests the initialization again, and so on. Exactly in almost every way like version you posted from Wikipedia, except using AMD64 assembly and the symbols/layout specified in the Itanium ABI.

Note that if you run that test you should give Singleton a non-trivial constructor so it's not a POD, otherwise the optimizer will realize that there's no point to doing all that guard/locking work.

Sign up to request clarification or add additional context in comments.

3 Comments

“// called automatically when the thread exits” -- do you mean the process exits? This pattern has nothing to do with the TLS, does it?
@kkm I meant process, yeah.
Thanks for the clarification! I was a bit confused by that! :)
30
// Singleton.hpp class Singleton { public: static Singleton& Instance() { static Singleton S; return S; } private: Singleton(); ~Singleton(); }; 

This implementation is known as Meyers' Singleton. Scott Meyers says:

"This approach is founded on C++'s guarantee that local static objects are initialized when the object's definition is first encountered during a call to that function." ... "As a bonus, if you never call a function emulating a non-local static object, you never incur the cost of constructing and destructing the object."

When you call Singleton& s=Singleton::Instance() first time the object is created and every next call to Singleton::Instance() results with the same object being returned. Main issue:


Another implementation is called the trusty leaky Singleton.

class Singleton { public: static Singleton& Instance() { if (I == nullptr) { I = new Singleton(); } return *I; } private: Singleton(); ~Singleton(); static Singleton* I; }; // Singleton.cpp Singleton* Singleton::I = 0; 

Two issues:

  • leaks, unless you implement a Release and make sure to call it (once)
  • not thread safe

3 Comments

For leaky singleton, why not static Singleton& Instance() { static Singleton *I = new Singleton(); return *I; }.
in your code Singleton s=Singleton::Instance(), ain't you actually creating a new instance via the default (non-private) copy constructor? ( I would have imagined Singleton & s=Singleton::Instance() instead)
Note: since C++11 (but only MSVC 14+, prior versions where not compliant), if you use a local static as suggested by @JefferyThomas, then this is even thread-safe :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.