title: Kernel-like Module initialization in C
body: <p>I have a C/C++ project with lots of modules that are meant to be added and removed among installations (they are like "plugins"). I wanted to greatly simplify the module initialization using a technique similar to Linux Kernel - whenever the kernel is linked with some .c module, the module_init() macro in the .c file "registers" the module at some global site so it can be callback'd later to get properly initialized.</p>
  
  <p>Question: How do I do this without some nasty linking tricks?</p>
  
  <p>I tried one approach, roughly following:</p>
  
  <p>all modules have module_init(initfunc) macro inside that expands into something like</p>
  
  <pre><code>struct _initializer_ {
    _initializer_() {
      register_init_function(initfunc);
    }
  } _init_instance_;
  </code></pre>
  
  <p>The register_init_function stores the initfunc pointer a list, so it can be initialized by the main program later.</p>
  
  <p>Problem here is that the C global variables get all zeroed before use in uncontrollable order, so it happens that some modules are properly registered, while registration of others gets erased when the main module is "initialized" after them. I also tried some tricks with class-static vs. global variable initialization order, but either completely misunderstood the description or they don't work.</p>
  
  <p>Question: Is there some method to somehow ensure initialization order, or a whole other method to do such module initialization?</p>
  
  <p>[EDIT] straightforward explanation:</p>
  
  <ul>
  <li>main.c has global variable Y</li>
  <li>main.h describes that global variable or some possible way to modify it (function X())</li>
  <li>module.c calls function X() (or any other Y-modifying thingy) to save something to variable Y as soon as possible, <strong>without being referenced from main.c</strong>.</li>
  <li>main.c can after that see that someone called X() and saved stuff into Y.</li>
  </ul>
  
  <p>Example purpose: gcc main.c modules/common/<em>.c modules/some_specific_purpose/</em>.c</p>