C++ in Linux: global object initialization hell!

Started by
16 comments, last by Castaa 15 years, 7 months ago
Quote:Original post by bubu LV
You also can (but should not!) change initialization order with init_priority attribute (GCC only).

And if you want the same thing with MS's compiler, then there's init_seg.
Advertisement
Quote:Original post by TheFlyingDutchman

This works perfectly for me, no need for global variables this way and I am still able to destruct the Window instance in the way I want. Example usage:

*** Source Snippet Removed ***


int main(int argc, char **argv){    try    {      Window window;      Game game(window);      game.run();    }    catch (std::exception & e)    {      cerr << "Error: `" << e.what() << "'." << endl;      return 1;    }    return 0;}

No cleanup needed, systems are clearly inter-connected during construction, and you're guaranteed proper de-initialization order.

Your approach is fine - but it's idiomatic for C. C++ offers implicit construction/destruction. The above style does exactly the same, yet if applied throughout the project, results in simpler and more robust code, that does not suffer from undefined behavior.

And most importantly, every C++ class has initialize(), destroy() and instance() functions already. They're constructor, destructor and instance respectively.

Allocating something statically brings along many issues which are very rarely required.
Quote:Original post by Antheus
Quote:Original post by TheFlyingDutchman

This works perfectly for me, no need for global variables this way and I am still able to destruct the Window instance in the way I want. Example usage:

*** Source Snippet Removed ***


int main(int argc, char **argv){    try    {      Window window;      Game game(window);      game.run();    }    catch (std::exception & e)    {      cerr << "Error: `" << e.what() << "'." << endl;      return 1;    }    return 0;}

No cleanup needed, systems are clearly inter-connected during construction, and you're guaranteed proper de-initialization order.

Your approach is fine - but it's idiomatic for C. C++ offers implicit construction/destruction. The above style does exactly the same, yet if applied throughout the project, results in simpler and more robust code, that does not suffer from undefined behavior.

And most importantly, every C++ class has initialize(), destroy() and instance() functions already. They're constructor, destructor and instance respectively.

Allocating something statically brings along many issues which are very rarely required.


We were talking about singletons and their purpose is to be single. So no multiple instances of a singleton class are allowed. Therefore you make the constructor, copy constructor and destructor (and probably also operator=) private. This way the user can only obtain a reference to the instance and he can not accidentally delete the instance (what would happen, if in another location in the code you rely on that instance already being initialized, while you accidentally deleted it in another place? That should not be allowed, therefore the destructor is private).

So with this setup, you don't allow the user to create more instances of the class. He gets the advantage that the instance is globally available. The disadvantage is that you don't have implicit destruction. Therefore the static destroy member is added.

Quote:Original post by DevFred
Quote:Original post by TheFlyingDutchman
I am using this singleton class setup for almost any class [...] that I need only one instance for

NEEDING one instance and NOT ALLOWING MORE THAN one instance is not the same. You are abusing the singleton pattern.

Well, I think the examples I gave are pretty good examples of classes you only want one instance: Window, Game, Libraries. Typical classes that need only one instance (and why allow more of them? If my design is such that there is a single GlslLibrary, then my design should force that there is only one such library).
I suspected this would turn into another singleton thread after TheFlyingDutchman's post, might as well close it now :)
Quote:Original post by dmail
I suspected this would turn into another singleton thread after TheFlyingDutchman's post, might as well close it now :)


Ah, sorry about that. I wasn't aware that singletons are more often discussed (perhaps even debated on) in this forum. I'll shut up from now on, I promise ;). Anyway, the topic starter now knows about singletons (maybe he did already before this topic) and if he thinks it is useful, he can use them. No need to discuss them further I guess.
Quote:Original post by TheFlyingDutchman

Well, I think the examples I gave are pretty good examples of classes you only want one instance: Window, Game, Libraries. Typical classes that need only one instance (and why allow more of them? If my design is such that there is a single GlslLibrary, then my design should force that there is only one such library).


Window - There is nothing anywhere that would in any way under any system mandate there may only ever be one. Often, there is no need for more than one, but claiming there can never be one is simply redundant.

There's games that run on 3 monitors. I believe Doom supported that in one of later patches. Flight simulator runs on arbitrary number of monitors.

Window is definitely not suitable for that.

Game is a binder class. The singleton advice is terrible if discussed in scope of Java. If I want a trivial multi-player application server (doesn't need to be networked), I will definitely want more than one Game. I'll want a game per player. Again, there is niche area where Game may be global (emphasis *may*). There's no reason where it should be *must*.

GlslLibrary - Does that happen to use C API that's defined over static context? If so, it can be wrapped well into RAII to encapsulate required functionality, yet retain the benefit of C++. If library exists in some static context, then it needs to be static. It may even be global (but doesn't need to be).

Everybody *must* die. Everybody *may* eat. And just because not eating causes one to die, doesn't mean they shouldn't bother.
For what it's worth, if you have global pointers instead of global objects, you can initialize them whenever and however you want in main(), or some function called more or less directly by it. Problem solved, except for the problem of having globals at all.

Maybeyou could just re-factor your globals not to have dependencies on each other?
Thanks to all that replied. I learned a lot from this thread.
_________________________My game: Star Sonatahttp://www.starsonata.com

This topic is closed to new replies.

Advertisement