init code in header-only library

C

Christof Warlich

Hi,

I'm working on a (template) library that is up to now entirely
implemented in header-files. This makes the library quite convenient to
use as no extra object code needs to be linked when using the library.
But now, the library needs to run some initialization code at system
startup. Usually, this initialization code would be called from a .cc
file once at system startup, e.g. by assigning the init function to a
global variable:

// init.cc
#include <stdio.h>
inline int init() {
// whatever needs to be initialized goes here
printf("initializing\n");
return 0;
}
static int dummy = init();

With this simple approach, calling init() cannot be done from a header
file, as it will be called as often as it will be included by .cc files.
Thus, it is required to link the application with the object derived
from init.cc now.

To avoid this, I replaced the above with the following code, now having
everything defined in a header file:

// init.h
#include <stdio.h>
inline int init() {
// whatever needs to be initialized goes here
printf("initializing\n");
return 0;
}
// ensure that init is called exactly once
inline int initialize(void) {
static int dummy = init();
return 0;
}
static int dummy = initialize();

This works as desired: With the two sample application files one.cc and
two.cc:

// one.cc
#include "init.h"
int main(void) {
return 0;
}

// two.cc
#include "init.h"

and compilation:

$ g++ -I. one.cc two.cc

the init() function is only called once:

$ ./a.out
initializing

The only concern is that a new global dummy variable will be created for
every application file that includes init.h. Any ideas to avoid this?

Christof
 
C

Christof Warlich

Victor said:
No offence, but you're trying to avoid using object modules in your
library and still want to have a feature that is only possible to
have *if* your library has at least one object module.

Please have a closer look at the code example above: It shows that it
_is_ possible to execute initialization code exactly once before main()
_without_ the need of a dedicated library object module. The files
one.cc and two.cc are examples for application code that is _using_ the
library, hence including the library's interface definition, i.e. init.h
in the example above. Sorry that I haven't made that clear enough.

So why did I post, you may ask. Generally, I'm quite happy with this
solution, but it comes at the cost of needing the space of an integer
per application object file that uses the library (due to the global
dummy variable). Thus, I'm asking for ideas if this could be avoided or
at least be minimized. All I could think of so far was to make dummy a
char instead of an int to reduce the amount of memory being occupied.
 
C

Christof Warlich

Paavo said:
You have several choices, and you have to make some compromises:

1) put a call to initialize() in the beginning of each public function.
If the functions are mostly longer than 3 lines, the cost is probably
negligible. ......
5) your current approach, making a static per each TU. The cost is
probably negligible unless the client project has thousands of nearly
empty source files.

I think I would pick 1) myself. But 5) is also quite attractive. It has
the nice feature of circumventing the statics initialization order
problem in different TU-s, inherent to 3).

hth
Paavo
Thanks for summing up the options, in particular for 1) , which I have
not considered so far. Getting someone else's view is always good to
avoid stupid design decisions. Anyway, I will stick to 5), as some of my
library functions will be very short, i.e. one-liners. And you are
absolutely right that the memory cost will be neglectable for almost all
real world applications using the library.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top