Sign in to follow this  

Managing static initialization/deinitialization order

This topic is 674 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The problem is rather simple: I have two core classes that need to be initialized first and deinitialized last.

 

1) The memory manager is created on heap when the first allocation occurs via raw new() and needs to be destroyed no sooner than just before...

2) ... the log class, which is a statically allocated compound object that contains no dynamic allocations, but needs to be the very last thing to be deinitialized. What makes it a bit more complicated is that the log class in turn contains pointers to one or more static stream objects. Here's a short snippet to demonstrate:

//log.h
extern log_static log;

//log.cpp
log_static log; 

//main.cpp
#include "log.h"

//output dispatchers, they have minimum state, but contain no dynamic allocations of memory inside the app itself (calls like AllocConsole() etc notwithstanding)
static log_backend_console  log_console;
static log_backend_ofstream log_ofstream;

int main()
{
  log_static.add_dispatcher(&log_console);
  log_static.add_dispatcher(&log_ofstream);

  //do programy stuff...

  return 1;

  //perform static deallocation. Want to force order: unwind everything else, then destroy log, then log_console and log_ofstream
}

Freeing the memory manager on cue is easy - I can just add it to the log's dtor. Also, as far as I can tell, under C++0x and later the global initialization stack is unwound in reverse order on program exit, meaning that stuff will be deinitialized in reverse order per compilation unit (which would mean to me that static objects initialized at the top of a cpp file will be deinitialized last). As far as I understand the order in which compilation units are processed, though, is completely undefined.

 

The reason why I'm so concerned with this is threefold: 1) because I have a poo-ton of source files that contain all kinds of extraneous stuff (such as global variables) that are leftovers that I want to remove. I also want to remove potential race conditions/implicit ordering problems for static objects that might cause the program to crash on exit, 2) I want to be able to debug and datamine my memory manager for leaks outside of normal execution by dumping unallocated blocks on exit, which currently doesn't work, because the log class is being freed before deinitialization concludes, and 3) for the sake of completeness.

 

I'd also like the solution to be compiler and platform agnostic, although I'd be happy with just supporting Visual Studio for the time being. 

 

Is what I'm asking too much or can I perform some voodoo to have the log streams and log class itself be initialized first and deinitialized last?

Share this post


Link to post
Share on other sites

 

Why not just use RAII to order these manually?

int main() {
  RAIIHandle s1 = static1.init();
  RAIIHandle s2 = static2.init();
 
  // do programy stuff...
  
  return result;
  // RAIIHandles are destructed here, in reverse order of initialisation
}

 

Welp - those are two hours of overthinking I'm never getting back...

Share this post


Link to post
Share on other sites

Please be aware that if there are any static variables defined anywhere in the program, there is no guarantee that the above will work.


Correct, but the point is to not have static variables of that sort. If anything requires side-effects to initialize or deinitialize in any way, it truly really definitely should rely on main() explicitly initializing it and (either via RAII or explicit calls) deinitializing it.

Share this post


Link to post
Share on other sites

This topic is 674 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this