Thread safety problems with function scope static variables vs class static private members

Discussion in 'C++' started by Hicham Mouline, Dec 18, 2008.

  1. I have a function f that is called from multiple threads
    I have the choice between setting a const int array as a static local in f()

    void C::f() {
    static const int keys[] = { 0, ...., 15 };
    }

    or as a private member of C

    class C {
    private:
    static const int keys[] ;
    };
    const int C::keys[] = { 0....15 };



    1 In theory?
    Is there a risk that keys are initialized badly because keys is a static
    local variable of f (keys init'ed only first time exec enters f)
    while no risk when keys is a static member of C (because keys is init'ed
    before runtime passes through main even)?
    I know c++03 says nothing about threads. Can one still infer anything from
    it?

    2 In practise, (msvc, g++, intel....)
    Do these make sure keys init as function local is ok, and as a member of C
    also?

    regards,
     
    Hicham Mouline, Dec 18, 2008
    #1
    1. Advertising

  2. Hicham Mouline

    James Kanze Guest

    Re: Thread safety problems with function scope static variables vsclass static private members

    On Dec 18, 6:41 pm, "Hicham Mouline" <> wrote:
    > I have a function f that is called from multiple threads I
    > have the choice between setting a const int array as a static
    > local in f()


    > void C::f() {
    > static const int keys[] = { 0, ...., 15 };
    > }


    > or as a private member of C


    > class C {
    > private:
    > static const int keys[] ;};


    > const int C::keys[] = { 0....15 };


    > 1 In theory?
    > Is there a risk that keys are initialized badly because keys
    > is a static local variable of f (keys init'ed only first time
    > exec enters f) while no risk when keys is a static member of C
    > (because keys is init'ed before runtime passes through main
    > even)? I know c++03 says nothing about threads. Can one still
    > infer anything from it?


    No. In both cases, you have static initialization, which is
    guaranteed to occur before anything else.

    > 2 In practise, (msvc, g++, intel....)
    > Do these make sure keys init as function local is ok, and as a
    > member of C also?


    As long as it is static initialization, there can be no problem.
    Note that for it to be static initialization, the type in
    question must be a POD, and all of the initialization
    expressions must be constant expressions. But I regularly use
    such things to avoid order of initialization issues.

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Dec 18, 2008
    #2
    1. Advertising

  3. Hicham Mouline

    Fred Zwarts Guest

    "Hicham Mouline" <> wrote in message news:494a8b66$0$90263$...
    >I have a function f that is called from multiple threads
    > I have the choice between setting a const int array as a static local in f()
    >
    > void C::f() {
    > static const int keys[] = { 0, ...., 15 };
    > }
    >
    > or as a private member of C
    >
    > class C {
    > private:
    > static const int keys[] ;
    > };
    > const int C::keys[] = { 0....15 };
    >
    >
    >
    > 1 In theory?
    > Is there a risk that keys are initialized badly because keys is a static
    > local variable of f (keys init'ed only first time exec enters f)
    > while no risk when keys is a static member of C (because keys is init'ed
    > before runtime passes through main even)?


    Who says that threads are not created before main is started?
    Thread safety is required even before main in started.
     
    Fred Zwarts, Dec 19, 2008
    #3
  4. Hicham Mouline

    James Kanze Guest

    Re: Thread safety problems with function scope static variables vsclass static private members

    On Dec 19, 9:25 am, "Fred Zwarts" <> wrote:
    > "Hicham Mouline" <> wrote in
    > messagenews:494a8b66$0$90263$...
    > >I have a function f that is called from multiple threads
    > > I have the choice between setting a const int array as a
    > > static local in f()


    > > void C::f() {
    > > static const int keys[] = { 0, ...., 15 };
    > > }


    > > or as a private member of C


    > > class C {
    > > private:
    > > static const int keys[] ;
    > > };
    > > const int C::keys[] = { 0....15 };


    > > 1 In theory?
    > > Is there a risk that keys are initialized badly because keys
    > > is a static local variable of f (keys init'ed only first
    > > time exec enters f) while no risk when keys is a static
    > > member of C (because keys is init'ed before runtime passes
    > > through main even)?


    > Who says that threads are not created before main is started?


    The coding guidelines.

    > Thread safety is required even before main in started.


    If your coding guidelines allow creating threads in the
    constructors of objects with static lifetime. Most I've seen
    don't---threading is hard enough to get right without going out
    of your way to make it more difficult.

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Dec 19, 2008
    #4
  5. Re: Thread safety problems with function scope static variables vsclass static private members

    James Kanze wrote:
    > On Dec 18, 6:41 pm, "Hicham Mouline" <> wrote:
    >> void C::f() {
    >> static const int keys[] = { 0, ...., 15 };
    >> }

    >
    > No. In both cases, you have static initialization, which is
    > guaranteed to occur before anything else.


    I thought that a static inside a function is initialized the first
    time the function is called?

    The above function might not be problematic with regard to thread
    safety, but what about something like this:

    void foo()
    {
    static SomeClass object;
    ...
    }

    Suppose that 'foo()' may be called from more than one thread. Can it
    happen that 'object' is constructed more than once? (Worse: Can it
    happen, that while the constructor of 'object' is being executed, a
    second thread causes it to be called again?)

    Assume that SomeClass, for example, allocates memory into a member
    pointer, or does something else which would cause a serious malfunction
    if the constructor were to be called more than once.
     
    Juha Nieminen, Dec 19, 2008
    #5
  6. Hicham Mouline

    James Kanze Guest

    Re: Thread safety problems with function scope static variables vsclass static private members

    On Dec 19, 12:49 pm, Juha Nieminen <> wrote:
    > James Kanze wrote:
    > > On Dec 18, 6:41 pm, "Hicham Mouline" <> wrote:
    > >> void C::f() {
    > >> static const int keys[] = { 0, ...., 15 };
    > >> }


    > > No. In both cases, you have static initialization, which is
    > > guaranteed to occur before anything else.


    > I thought that a static inside a function is initialized the
    > first time the function is called?


    The standard explicitly says otherwise: "Objects of POD types
    with static storage duration initialized with constant
    expressions shall be initialized before any dynamic
    initialization takes place." (§3.6.2/1).

    In fact, in this case, the word static means what it says; such
    variables are initialized statically, not dynamically.

    > The above function might not be problematic with regard to
    > thread safety, but what about something like this:


    > void foo()
    > {
    > static SomeClass object;
    > ...
    > }


    It depends on SomeClass, obviously. Does SomeClass use static
    or dynamic initialization?

    > Suppose that 'foo()' may be called from more than one thread.
    > Can it happen that 'object' is constructed more than once?


    Probably. I don't know what the next version of the standard
    will say about it, but in current implementations, it's
    undefined behavior to enter such a function from several
    different threads without some sort of external synchronization.

    But what does this have to do with static initialization?

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Dec 19, 2008
    #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. Paul Opal
    Replies:
    12
    Views:
    985
    Paul Opal
    Oct 11, 2004
  2. SaravanaKumar
    Replies:
    6
    Views:
    9,485
    Tony Morris
    Oct 19, 2004
  3. CoolPint
    Replies:
    8
    Views:
    1,011
    Jeff Schwab
    Dec 14, 2003
  4. Replies:
    2
    Views:
    836
    Noah Roberts
    Jun 9, 2006
  5. Replies:
    5
    Views:
    647
    Chris Thomasson
    Aug 23, 2007
Loading...

Share This Page