Order of initialization problems become particularly difficult to handle in concurrent code. It is usually best to avoid global (namespace scope) objects altogether.
What does order of initialisation of globals have to do with multithreaded code? (I hope nobody is creating global threads ...)
BTW, singletons with lazy initialisation were a sollution to the initialisation order issue, isn't it?
Singletons should never be the solution to anything.
Singletons can solve some problems related to the orderinf of static initializations, but then you get all the problems related to Singletons. They are also recommended against in guideline: I.3: Avoid singletons
There are better solutions to that problem that do not introduce more problems, or at least they do not introduce problems that are as large.
but then you get all the problems related to Singletons.
Could you name some of them? The usual ones are related to the fact that they are global, mutable variables which isn't really a disadvantage when talking about a replacement for "normal" global mutable variables.
Doesn't mean they shouldn't be avoided, but I agree with @imre-palik, that the cited comment conflates two unrelated problems.
Sure, here are a few (by no means all of the) problems with Singletons:
The implementation of most Singletons is not thread safe, it's not hard to make them thread safe they just aren't most the time. So it often falls on the consumer to use them in a safe manner. This removes any simplification the Singleton may have provided.
The Singleton pattern is abused easily. It is rare that a Singleton does something that there must only be one of.
I've seen good Singletons, I've seen global objects that manage the state for graphics cards, sound card handles and for managing hardware handles that really should only have one object. It can really screw up a machine have two different handles to the same graphics cards floating around and two different chunks of code using them.
This isn't most Singletons, they have been abused for myriad of things that I would like to have multiples of for variety of reasons that the creator of the API couldn't have had in mind. Some of these things include SQL connection pools, application configuration, thread pools, clocks, random number generators, API handles/contexts and about a dozen other kind of objects that would be better suited as a value class.
Singletons generally force someone in this position to construct another Singleton and swap out objects during the build of test executables. I would argue this is something the majority of developers don't even know can be done, and even for those who know it can be done mucking around with the build system for sake of tests it's often not something that can be justified. When is justified it can lead to situations that are error-prone and reduces confidence in the tests.
If the class in question could accept a database connection as a parameter or template parameter this could be avoided a few different ways. In general this more normal kind ofcomposition results in more usable and more cleanly encapsulated code.
To summarize, singletons are rarely actually needed and they are easy to abuse. This abuse causes far-reaching problems in the code base by making testing and thread safety more difficult and encouraging the use of more globals.
It sounds like the existing text is correct -- is anyone still asking for a change to the existing text?
I still don't understand how the order of initialisation issues are increased by multithreaded code.
One example is threads that start before main.
Another example is the rules for thread_local variables, where you use dynamic initialization it can cause the initialization of every thread_local and so can call arbitrary amounts of code. (This came up a few days ago on the committee reflectors and I'm just echoing the comment here without elaboration as I haven't closely watched that particular issue.)
Then could we (also) have a guideline stating not to start a thread befor main?
Most helpful comment
Singletons should never be the solution to anything.