Re: (non)-execution of namespace-local initializers

Discussion in 'C++' started by Stephan Br?nnimann, Sep 10, 2004.

  1. (James Hopkin) wrote in message news:<>...
    > "Simon Greenwold" <> wrote in message news:<chl6sj$9u0$>...
    > >
    > > But initially I used "const bool registered = ", and the line was never
    > > executed. Why not? I have optimizations off. (I am using VC++7.1)
    > >

    >
    > Unfortunately, the function is not required to be called in either
    > case.
    >
    > Namespace scope variables need only be initialised before the first
    > call of any function defined in the translation unit.


    Where is defined in the standard?

    > You have
    > something of a chicken and egg situation going on there.
    >
    > I've had the same problem with my factory system, although the problem
    > surfaced a lot later. I was using registration objects, something like
    >
    > struct RegisterClassCreator
    > {
    > RegisterClassCreator(/* params */)
    > {
    > Factory::getInstance()->registerClassCreator(name, func);
    > }
    > };
    >
    > so that, instead of your 'bool registered =' line, I would have
    >
    > RegisterClassCreator reg("ConcreteProduct", CreateConcreteProduct);
    >
    > This actually worked fine (on three different platforms and
    > compilers), and has shipped in that form, but I've since found I can't
    > build these factory objects in a separate library on some platforms.
    >


    Is reg in the anonymous namespace? If so: why, contrary to your statement
    above, does it get initialized?

    > My current (standard compliant) system has a central registration
    > function per module, but I'm not entirely happy with that.
    >
    > Any other suggestions would be highly appreciated.


    This is of comp.lang.c++.moderated now, rather UNIX related:

    The registration class logic (see also Scott Meyers MEC++) only works
    if you link against the object file foo.o. If you build a static library and
    the program never explicitly calls a function or uses a variable
    defined in that library the symbols libtest.a(foo.o) will never be loaded
    and thus the registration does not take place.

    Anybody knows how this works with shared libraries?

    Stephan Brönnimann

    Open source rating and billing engine for communication networks.

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Stephan Br?nnimann, Sep 10, 2004
    #1
    1. Advertising

  2. Stephan Br?nnimann

    Guest

    (Stephan Br?nnimann) wrote in message
    news:<>...
    > (James Hopkin) wrote in message
    > news:<>...


    > > "Simon Greenwold" <> wrote in message
    > > news:<chl6sj$9u0$>...


    > > > But initially I used "const bool registered = ", and the line was
    > > > never executed. Why not? I have optimizations off. (I am using
    > > > VC++7.1)


    > > Unfortunately, the function is not required to be called in either
    > > case.


    > > Namespace scope variables need only be initialised before the first
    > > call of any function defined in the translation unit.


    > Where is defined in the standard?


    §3.6.2/3. In fact, the text in question seems to be intented to allow
    dynamic linking. Which is a bit silly, since there are enough other
    things present which make explicit dynamic linking undefined from the
    standards point of view, and of course, if you are using an
    implementation specific extension, you sort of expect to have to follow
    rules specific to that extension.

    Anyway, the question is, IMHO moot. All current compilers that I've
    heard about initialize static objects before main, and I suspect that
    there is enough code in existance which depends on it to prevent any
    compiler in the future from doing otherwise.

    > > You have something of a chicken and egg situation going on there.


    > > I've had the same problem with my factory system, although the
    > > problem surfaced a lot later. I was using registration objects,
    > > something like


    > > struct RegisterClassCreator
    > > {
    > > RegisterClassCreator(/* params */)
    > > {
    > > Factory::getInstance()->registerClassCreator(name, func);
    > > }
    > > };


    > > so that, instead of your 'bool registered =' line, I would have


    > > RegisterClassCreator reg("ConcreteProduct", CreateConcreteProduct);


    > > This actually worked fine (on three different platforms and
    > > compilers), and has shipped in that form, but I've since found I
    > > can't build these factory objects in a separate library on some
    > > platforms.


    > Is reg in the anonymous namespace? If so: why, contrary to your
    > statement above, does it get initialized?


    What statement? He said that the standard allowed it not to be
    initialized. Which is true. He says that it actually works fine, with
    all compilers he has tried. That corresponds to my experience as well;
    compilers in fact always initialize static objects before main.

    > > My current (standard compliant) system has a central registration
    > > function per module, but I'm not entirely happy with that.


    > > Any other suggestions would be highly appreciated.


    > This is of comp.lang.c++.moderated now, rather UNIX related:


    > The registration class logic (see also Scott Meyers MEC++) only works
    > if you link against the object file foo.o. If you build a static
    > library and the program never explicitly calls a function or uses a
    > variable defined in that library the symbols libtest.a(foo.o) will
    > never be loaded and thus the registration does not take place.


    That has nothing to do with Unix. It is the very definition of how a
    library works. On any system. Telling the linker to include a library
    does NOT tell it to incorporate all of the object files in the library.

    At some point in the development, you must have a list of all of the
    modules concerned. It may be in a makefile, it may even be in the
    makefile which builds the library, but it must be somewhere. Given
    that, it isn't too complicated to add whatever is necessary in the
    makefile to ensure that they get linked: extract the object files and
    add them to the link command, generate a C++ source file with explicit
    references and compile that, etc.

    > Anybody knows how this works with shared libraries?


    I presume you mean dynamically linked modules. These aren't libraries,
    but partially pre-linked object files (at least in the systems I'm
    familiar with). They thus follow the rules of object files, and not of
    libraries -- you either get all of the module, or none of it.

    Note, however, that dynamic initialization for dyanmically linked
    objects won't be called until the objects are actually linked. So if
    you're counting on a reference to the object to trigger the link, you're
    back where you started from.

    --
    James Kanze GABI Software http://www.gabi-soft.fr
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    , Sep 13, 2004
    #2
    1. Advertising

  3. Stephan Br?nnimann

    James Hopkin Guest

    (Stephan Br?nnimann) wrote in message news:<>...
    > >
    > > Namespace scope variables need only be initialised before the first
    > > call of any function defined in the translation unit.

    >
    > Where is defined in the standard?
    >


    3.6.2/3

    Footnote 31 appears to state that the object must be initialised at
    some point, but since it can be deferred indefinitely, that's not
    helpful.


    > >
    > > RegisterClassCreator reg("ConcreteProduct", CreateConcreteProduct);
    > >

    >
    > Is reg in the anonymous namespace? If so: why, contrary to your statement
    > above, does it get initialized?
    >


    Maybe I should have been clearer: my code was wrong, but happened to
    work on several platforms.


    >
    > The registration class logic (see also Scott Meyers MEC++) only works
    > if you link against the object file foo.o. If you build a static library and
    > the program never explicitly calls a function or uses a variable
    > defined in that library the symbols libtest.a(foo.o) will never be loaded
    > and thus the registration does not take place.
    >


    I believe this is a symptom of the code being non-standard. The same
    applies with Win32 libs.


    James

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    James Hopkin, Sep 13, 2004
    #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. Glen Able

    Class variable initializers

    Glen Able, Jan 29, 2004, in forum: Java
    Replies:
    0
    Views:
    345
    Glen Able
    Jan 29, 2004
  2. j l
    Replies:
    5
    Views:
    408
    A. Bolmarcich
    Feb 23, 2004
  3. Johannes Bauer
    Replies:
    25
    Views:
    8,547
    James Kanze
    Jul 31, 2010
  4. Fred the Freshwater Catfish

    Non-constant initializers

    Fred the Freshwater Catfish, May 12, 2011, in forum: C Programming
    Replies:
    87
    Views:
    1,813
    Shao Miller
    May 19, 2011
  5. Artur Ergashev
    Replies:
    0
    Views:
    309
    Artur Ergashev
    Aug 15, 2011
Loading...

Share This Page