init code in header-only library

Discussion in 'C++' started by Christof Warlich, Nov 18, 2008.

  1. 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
     
    Christof Warlich, Nov 18, 2008
    #1
    1. Advertising

  2. Victor Bazarov schrieb:
    >> 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?

    >
    > 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.
     
    Christof Warlich, Nov 19, 2008
    #2
    1. Advertising

  3. Paavo Helde schrieb:
    > 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.
     
    Christof Warlich, Nov 19, 2008
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tony Cheng
    Replies:
    1
    Views:
    8,258
    Juan T. Llibre
    Feb 24, 2006
  2. Replies:
    1
    Views:
    671
    Jules
    Aug 18, 2005
  3. Jess
    Replies:
    4
    Views:
    457
  4. mlt
    Replies:
    2
    Views:
    881
    Jean-Marc Bourguet
    Jan 31, 2009
  5. news.aon.at
    Replies:
    11
    Views:
    658
    Ian Collins
    Jan 29, 2011
Loading...

Share This Page