Initialization of local statics

Discussion in 'C++' started by Marcel Müller, Sep 26, 2010.

  1. Hi,

    the following code

    #include <stdio.h>

    struct A
    { A() { puts("A()"); }
    ~A() { puts("~A()"); }
    };

    static const A& foo()
    { puts("foo()");
    static const A var;
    return var;
    }

    int main()
    {
    puts("main()");
    foo();
    foo();
    return 0;
    }

    prints

    main()
    foo()
    A()
    foo()
    ~A()

    So var inside foo is initialized after the first pass of the code over
    the variable definition. Well, that would be useful in conjunction with
    templates to achieve late initialization and avoid static initialization
    dependencies.
    But is this execution order guaranteed? (I guess yes.) And if so, what
    does this mean with respect to threads?
    If this is not thread safe one could never store non POD constants in
    local statics in a multi threaded application, even if the underlying
    object type provides thread safety for const methods, isn't it?


    Marcel
     
    Marcel Müller, Sep 26, 2010
    #1
    1. Advertising

  2. Marcel Müller <> wrote:
    > But is this execution order guaranteed? (I guess yes.)


    AFAIK, yes. It can sometimes be a handy trick for executing code lazily
    only when needed (code which has to be executed only once, of course),
    without having to explicitly put a boolean somewhere to see if the code
    has already been executed or not, for example:

    void foo()
    {
    static SomeClass someObject = someReallyExpensiveFunction();
    ...
    }

    > And if so, what
    > does this mean with respect to threads?


    AFAIK the current standard takes no stance on thread-safety on anything
    (I'm not even sure it does so even for malloc()/new, even though in
    practical implementations those always are). Hence I don't think the
    standard guarantees thread-safety for initializing local statics either.
    (In other words, if two threads call the function simultaneously, the
    initialization of the static object might get screwed up, unless the
    compiler itself guarantees mutual exclusion.)
     
    Juha Nieminen, Sep 26, 2010
    #2
    1. Advertising

  3. Juha Nieminen wrote:
    >> And if so, what
    >> does this mean with respect to threads?

    >
    > AFAIK the current standard takes no stance on thread-safety on anything
    > (I'm not even sure it does so even for malloc()/new, even though in
    > practical implementations those always are). Hence I don't think the
    > standard guarantees thread-safety for initializing local statics either.
    > (In other words, if two threads call the function simultaneously, the
    > initialization of the static object might get screwed up, unless the
    > compiler itself guarantees mutual exclusion.)


    Just decompiled the binary. You are right, at least gcc 3.3.5 makes
    absolutely no protection around the flag.

    Maybe because it might be quite expensive, since other threads must be
    blocked during the initialization. Of course, the runtime overhead on
    each evaluation can be close to zero by using a double check. But we
    still need a synchronization resource for each static object. This is
    most likely the major drawback.


    Marcel
     
    Marcel Müller, Sep 26, 2010
    #3
  4. Marcel Müller <> writes:

    > But is this execution order guaranteed? (I guess yes.) And if so, what
    > does this mean with respect to threads?


    The C++03 standard doesn't say anything about threads at all, and so any
    compiler that supports threads can do whatever it likes. gcc has a
    compiler flag that selects whether or not such initialization is
    thread-safe, for example.

    The upcoming C++0x standard requires that the initialization of
    local-statics is thread-safe.

    Anthony
    --
    Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
    just::thread C++0x thread library http://www.stdthread.co.uk
    Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
    15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
     
    Anthony Williams, Sep 27, 2010
    #4
  5. Anthony Williams wrote:
    > The upcoming C++0x standard requires that the initialization of
    > local-statics is thread-safe.


    Ah! Nice to know.
    Even though I can't wait for this.


    Marcel
     
    Marcel Müller, Sep 27, 2010
    #5
  6. Paavo Helde wrote:
    > Marcel Müller <> wrote in news:4c9f442d$0
    > $6974$-online.net:
    >
    >> static const A& foo()
    >> { puts("foo()");
    >> static const A var;
    >> return var;
    >> }

    > [...]
    >> If this is not thread safe one could never store non POD constants in
    >> local statics in a multi threaded application, even if the underlying
    >> object type provides thread safety for const methods, isn't it?

    >
    > For making this thread-safe there is a simple approach not involving any
    > locking: just make sure that any such function is called at least once in
    > the beginning of main(), before any extra threads are created. This
    > assumes of course that no threads are created directly or indirectly
    > from constructors of static objects.


    Well, it might be not that simple to call a member function deep in the
    business logic without even having an object of the appropriate type.
    Furthermore if there is no need for delayed initialization, you could
    simply move the static object outside the method implementation in the
    compilation unit to achieve the same automatically. But then we are
    talking about the static initialization hell.

    > Note that there is a similar rule for program shutdown: one should take
    > care that all created threads are properly joined before program exit, so
    > the statics are destroyed in single-threaded mode.


    Never heard of that. But of course, it is straight forward to do so.
    Calling exit() with several active threads makes no sense anyway.
    Depending on the platform the result is completely different. WinXX
    AFAIK ends the application not before the last thread died. OS/2
    implicitly cancels all threads unconditional if thread 1 dies.


    Marcel
     
    Marcel Müller, Sep 27, 2010
    #6
    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. Jason

    Statics and connections

    Jason, Dec 6, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    1,792
    Jason
    Dec 6, 2004
  2. Roedy Green

    statics in inner classes

    Roedy Green, Jul 1, 2005, in forum: Java
    Replies:
    14
    Views:
    753
    Thomas G. Marshall
    Jul 12, 2005
  3. Roedy Green

    initialising statics

    Roedy Green, Jan 22, 2006, in forum: Java
    Replies:
    8
    Views:
    622
    John C. Bollinger
    Jan 27, 2006
  4. Stuart MacMartin
    Replies:
    5
    Views:
    581
    Victor Bazarov
    Jul 27, 2005
  5. Triple-DES
    Replies:
    5
    Views:
    308
    Irin Kotchencko
    May 29, 2008
Loading...

Share This Page