7

In C++ Singleton design pattern, obecalp mentioned that:

For many larger programs, especially those with dynamic libraries. Any global or static object that's none primitive can lead to segfaults/crashes upon program exit on many platforms due to order of destruction issues upon libraries unloading. This is one of the reasons many coding conventions (including Google's) ban the use of non-trivial static and global objects.

Can someone elaborate why this can happen? Maybe an example to explain it?

Community
  • 1
  • 1
Deqing
  • 14,098
  • 15
  • 84
  • 131
  • One example of this I encountered: trying to execute OpenGL functions from singleton destructor - by the time destructor was executed, Windows already automatically destroyed the window along with rendering context and unloaded OpenGL library. – user2802841 Jan 16 '14 at 09:33

2 Answers2

8

You may have heard of the static initialization order fiasco where a global being built references another global that is not yet built. The general solution to this issue is to use lazy initialized objects (initialization on first use).

Well, the same fiasco may occur at destruction time, if the destructor of an object references another object which is already destructed; and unfortunately there is no silver bullet solution to this issue since the code of a destructor can be arbitrarily complex.

One solution is simply to forbid the use of this ill-mannered feature.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • This is the main reason why the actual singleton object will be dynamically allocated, and never deleted. – James Kanze Jan 16 '14 at 09:47
  • @JamesKanze: unfortunately, this causes issues too; even discounting the fact that you might actually want the destructor to be executed (say, because it flushes stuff to the disk for example) when you load/unload libraries at runtime, a library that does not properly dispose of the singletons it allocated is just *leaky*. – Matthieu M. Jan 16 '14 at 09:55
  • If you're constantly loading and unloading a library, you've got problems in general. And while there are cases where you do want the destructor of a singleton to be called (I've got one which manages temporary files, and the destructor deletes them), they tend to be the exception. Most singletons should not be destructed. (And most libraries should be linked statically, so the issue of loading and unloading it won't occur.) – James Kanze Jan 16 '14 at 10:27
0

I am posting this as an answer, because I do not understand why this is not used:

Simply make one single global object on stack (from a class) and allocate every global you want into that one (member pointer, allocated on heap). You can have accessors for those global objects and then destroy them in the destructor of the global object, with perfect control over the order of construction/deconstruction of each.

Oh, and by the way, you can have locks in there too, including between the "global" objects.