1

I just realized that I have ended with the code bellow just to be able to do some initialization during startup. I am asking if I am missing something and there is some standard way to run some code during initialization, and especially if we can define the initialization order as required, because the initialization doesn't goes exactly as expected.

#define concat(a,b) a##b
#define autoname1(cnt) concat(autoname_,cnt)
#define autoname autoname1(__COUNTER__)

#define onStartupExecute_(func,structname) void func();\
          struct structname{structname(){func();}} autoname;

#define onStartupExecute(func) onStartupExecute_(func,autoname)

With the above code when e.g. we define:

void someInitialization(){doSomething1;doSomething2;}
onStartupExecute(someInitialization)

the code produced by onStartupExecuteis:

struct autoname_12{autoname_12(){someInitialization();}} autoname_13;

and so during startup before main the code someInitialization is executed.

I think there should be some more simple way to do it !

George Kourtis
  • 2,381
  • 3
  • 18
  • 28
  • 1
    What would be wrong with a function that performs the required initialization as the first statement of your `main()`? (Because it's quite unclear what you really want to achieve here) – JBL Sep 02 '14 at 07:57
  • `std::list> orderedStartupTasks;` ? – Piotr Skotnicki Sep 02 '14 at 07:59
  • @jbl Some initialization that happen later on e.g. by writing myString s="mykindofstrings"_my; depend on having initialized the relative garbage collected memory. – George Kourtis Sep 02 '14 at 08:14

2 Answers2

1

If the initialization code is splitted across several [independent] compilation units, then the solution with a single static list<function...> isn't convenient. You may use Nifty Counters to automatically order invocations of statically defined entities by their dependencies.

And yes, static instances of dedicated classes is the common way to perform some code before and after main(). You should remember that within a given compilation unit they are initialized in order of their definitions and destroyed in reverse order. The order of initialization between several independent compilation units (.o files) may vary and depends on the dependencies of the units. The NiftyCounter technique allows to order such modules more or less explicitly.

user3159253
  • 16,836
  • 3
  • 30
  • 56
  • Good to hear that this is the common way to perform some code before and after main(). My code is a unique compilation unit ( until now ) so I was supposing that the initialization should happen in the order the code is written, but it seems that it isn't so and I don't know neither what the standard says about that neither if I should assume that using g++. – George Kourtis Sep 02 '14 at 08:25
  • I have found the following SO QA: http://stackoverflow.com/questions/8433484/c-static-initialization-vs-attribute-constructor which describes GCC-specific way to control the order. By default static variables are initialized in order they appear in a given unit. – user3159253 Sep 02 '14 at 08:58
0

With GCC you could also give a priority to the constructor function attribute.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I suppose that is the correct answer at least when using gcc as the link says:"The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () completes or exit () is called. Functions with these attributes are useful for initializing data that is used implicitly during the execution of the program." So no reason for convoluted autogenerated constructor code. – George Kourtis Sep 02 '14 at 08:31