A global variable is more useful than singleton, since it comes with no battery, plan or pretense.
Singleton at minimal requires thread-safety, and that comes very hard. It also contradicts with itself when a singleton is made thread-specific variable (TLS) - because it's singleton / thread, but not per process.
> A global variable is more useful than singleton, since it comes with no battery, plan or pretense.
Initialization and deinitialization of globals in C++ is a trainwreck. A singleton wrapper like the one I proposed upthread gives you deterministic initialization order and doesn't impose a runtime performance penalty.
> Singleton at minimal requires thread-safety
Both Windows and POSIX have locks that can be statically initialized. In Windows,
Now you can serialize access to your singleton without having to do any explicit and delicate lock initialization. Of course, this isn't the only approach --- you can make the singleton itself threadsafe and have your generic singleton wrapper serialize initialization using a similar approach. TIMTOWTDI.
Why should a Singleton be thread safe? Nothing says that it will be used in a multi-threaded environment... For me a Singleton must fulfill the specification given by the Gang of Four.
I'm not saying that it should not be thought thread safe, I just say that it's not the point here.
g_current_context->Something() or
g_current_context::singleton()->Something()
Because I can set in a special place g_current_context to the initial value knowing it would be safe to do so, while the singleton is going to set it, once it's first needed, and that might not be appropriate.
The problem with singleton's is that initialization is not controlled - what if the singleton is for the first time called from function that already ate too much stack, and now the initialization routine for the singleton wants more?
What if it was called from thread? Or interrupt routine? Or during time sensitive operation that needs to finish on-time (like something producing audio samples, which called every 5ms, need to finish in 2-3ms).
Or callback that needs to return as soon as possible to the caller.
How are you going to deal with it then?
It's much better to be explicit in this case, have a safe place, where no threads are created yet and initialize it, without any protection needed, and then use it as global variable.
Even better, if possible, put all these variables in page (if the OS allows) - initialize them, and then make them READONLY - to know that's not going to change.
The only thing is that is not always easy to maintain an unique g_current_context across all your classes, specially if you have cross references between your headers. In those cases it is handy to have Sing::I().something() instead of local_pointer_to_context->something(), where you have to maintain several instances of the same context.
Again, singleton are known to do not be thread-safe so I am just talking about single thread apps (which still exists)
I understand your point of view, but that kind of problem is application specific. When we have to deal with these constraints, of course the use of a Singleton is dumb.
If I had to deal with these, I'll change my implementation to fit to my needs. That's all.
Maybe the term "generic" was too heavy for the use cases I described.
Singleton at minimal requires thread-safety, and that comes very hard. It also contradicts with itself when a singleton is made thread-specific variable (TLS) - because it's singleton / thread, but not per process.