Intialisation order and statics

Discussion in 'C++' started by Spacen Jasset, Jan 31, 2005.

  1. Since it says in the standard that the order of initialization of
    variables is indeterminate, does this also apply to a static within a
    function?

    e.g.

    int GetInt()
    {
    static int test = 458;
    return test;
    }


    when might test be initialized? Is it indeterminate like any other
    object. In other words calling GetInt() before main() is executed
    doesn't guarantee test has been initialized?

    If this is the case how does one avoid problems with static
    initialisation. For instance if I have a class A

    class A
    {
    MyMutex mutex;
    };

    A a_object;

    Here, let us say that MyMutex's constructor will read a static member
    variable within the MyMutex class. Presumably, this is undefined
    behavior since the static variable may not yet have been initialised.

    If that is the case how do you avoid this sort of trap?
     
    Spacen Jasset, Jan 31, 2005
    #1
    1. Advertising

  2. "Spacen Jasset" <> skrev i en meddelelse
    news:...
    > Since it says in the standard that the order of initialization of
    > variables is indeterminate, does this also apply to a static within a
    > function?
    >
    > e.g.
    >
    > int GetInt()
    > {
    > static int test = 458;
    > return test;
    > }
    >
    >
    > when might test be initialized? Is it indeterminate like any other object.
    > In other words calling GetInt() before main() is executed doesn't
    > guarantee test has been initialized?


    Calling GetInt assures that test will be initialised, thus you'll have no
    problems. In your case, test will be initialised automatically, but if you
    had a more complicated element (such as a mutex), the element will be
    initialised the first time you call the function.

    /Peter
    [snip]
     
    Peter Koch Larsen, Jan 31, 2005
    #2
    1. Advertising

  3. Peter Koch Larsen wrote:
    > "Spacen Jasset" <> skrev i en meddelelse
    > news:...
    >
    >>Since it says in the standard that the order of initialization of
    >>variables is indeterminate, does this also apply to a static within a
    >>function?
    >>
    >>e.g.
    >>
    >>int GetInt()
    >>{
    >>static int test = 458;
    >>return test;
    >>}
    >>
    >>
    >>when might test be initialized? Is it indeterminate like any other object.
    >>In other words calling GetInt() before main() is executed doesn't
    >>guarantee test has been initialized?

    >
    >
    > Calling GetInt assures that test will be initialised, thus you'll have no
    > problems. In your case, test will be initialised automatically, but if you
    > had a more complicated element (such as a mutex), the element will be
    > initialised the first time you call the function.
    >


    which has always been a puzzle to me concerning efficiency. Does it mean
    that at runtime there is a test in the function to see if the variable
    is initialized? In other word, is the code:
    void foo()
    {
    static int n = 4;
    //
    // ...
    //
    }
    equivalent (once compiled) to the code:
    static bool foo_run = false;
    void foo()
    {
    static int n;
    if (!foo_run) { n=4;foo_run=true; }
    //
    // ...
    //
    }

    If it is the case, then using static inside function (which I thought a
    good practice for it declares things closer to where it is needed) incur
    a potentially huge cost!!!

    Otherwise, I don't see how the generated compiled code can do without a
    dynamic test?!? Oh yes, it could change the pointer function of foo so
    the first time it points to the initialization of n and the second time
    to a couple instructions further! Is that true?

    > /Peter
    > [snip]
    >
    >
     
    =?ISO-8859-1?Q?Xavier_D=E9coret?=, Jan 31, 2005
    #3
  4. Spacen Jasset

    msalters Guest

    Xavier D├ęcoret wrote:

    [ function statics ]

    > which has always been a puzzle to me concerning efficiency. Does it

    mean
    > that at runtime there is a test in the function to see if the

    variable
    > is initialized? In other word, is the code:


    Probably, for complex cases.

    > void foo()
    > {
    > static int n = 4;
    > //
    > // ...
    > //
    > }
    > equivalent (once compiled) to the code:
    > static bool foo_run = false;
    > void foo()
    > {
    > static int n;
    > if (!foo_run) { n=4;foo_run=true; }
    > //
    > // ...
    > //
    > }
    >
    > If it is the case, then using static inside function (which I thought

    a
    > good practice for it declares things closer to where it is needed)

    incur
    > a potentially huge cost!!!


    Not as bad as you'd think. Modern CPUs use branch prediction, and they
    tend to do quite well on such biased tests. Some compilers can even
    tell the CPU that the branch is likely false, and only the first call
    will be slower - but you typically don't care about that case, since
    your initialization makes the function slower.

    > Otherwise, I don't see how the generated compiled code can do without

    a
    > dynamic test?!? Oh yes, it could change the pointer function of foo

    so
    > the first time it points to the initialization of n and the second

    time
    > to a couple instructions further! Is that true?


    One of the most obvious ways is to initialize n at program startup. In
    general, you can detect the ctor call if you're initializing a static
    class-type object. There's no way to see the initial value of static
    int n, so it may be initialized from the startup code along with the
    globals.

    Another way could be to use page faults on CPUs that support them.
    Don't allocate RAM for the static variable, trap the page fault and
    initialize the variable just-in-time (before the first read). In a
    modern OS the CPU has to do this test anyway, to deal with virtual
    memory.

    A similar solution is to place the code (not the data) in paged-out
    memory, and use the same trap to initialize the variable on the first
    call of the funtion.

    Regards,
    Michiel Salters
     
    msalters, Jan 31, 2005
    #4
  5. Peter Koch Larsen wrote:
    > "Spacen Jasset" <> skrev i en meddelelse

    ....
    > Calling GetInt assures that test will be initialised, thus you'll have no
    > problems. In your case, test will be initialised automatically, but if you
    > had a more complicated element (such as a mutex), the element will be
    > initialised the first time you call the function.
    >
    > /Peter
    > [snip]
    >
    >



    I see that. But what if GetInt() istself is called before main() starts
    to run. I.e. by something like this:


    int myint = GetInt();

    could test be uninitiaised at this point. In most cases it will be since
    the linker will most likly put myint in an initialised data segment.
    However, that isn't possible for a class object since it's constructor
    must be called. I don't see anything explicit in the standard that says
    static variables inside always get initialised when they are called.
     
    Spacen Jasset, Jan 31, 2005
    #5
  6. Spacen Jasset

    msalters Guest

    Spacen Jasset wrote:
    ....
    > I see that. But what if GetInt() istself is called before main()

    starts
    > to run. I.e. by something like this:
    >
    >
    > int myint = GetInt();
    >
    > could test be uninitiaised at this point. In most cases it will be

    since
    > the linker will most likly put myint in an initialised data segment.
    > However, that isn't possible for a class object since it's

    constructor
    > must be called. I don't see anything explicit in the standard that

    says
    > static variables inside always get initialised when they are called.


    6.7/4 states that
    "A local object of POD type (3.9) with static storage duration
    initialized
    with constant-expressions is initialized before its block is first
    entered."
    ( that covers your example of a static int )

    "An implementation is permitted to perform early initialization of
    other
    local objects with static storage duration under the same conditions
    that
    an implementation is permitted to statically initialize an object with
    static storage duration in namespace scope (3.6.2). Otherwise such an
    object is initialized the first time control passes through its
    declaration; such an object is considered initialized upon the
    completion
    of its initialization."

    which covers the more interesting cases of static objects with
    constructors that can be observed.

    HTH,
    Michiel Salters
     
    msalters, Jan 31, 2005
    #6
  7. msalters wrote:
    > Spacen Jasset wrote:
    > ...
    >
    >>I see that. But what if GetInt() istself is called before main()

    >
    > starts
    >
    >>to run. I.e. by something like this:
    >>
    >>
    >>int myint = GetInt();
    >>
    >>could test be uninitiaised at this point. In most cases it will be

    >
    > since
    >
    >>the linker will most likly put myint in an initialised data segment.
    >>However, that isn't possible for a class object since it's

    >
    > constructor
    >
    >>must be called. I don't see anything explicit in the standard that

    >
    > says
    >
    >>static variables inside always get initialised when they are called.

    >
    >
    > 6.7/4 states that
    > "A local object of POD type (3.9) with static storage duration
    > initialized
    > with constant-expressions is initialized before its block is first
    > entered."
    > ( that covers your example of a static int )
    >
    > "An implementation is permitted to perform early initialization of
    > other
    > local objects with static storage duration under the same conditions
    > that
    > an implementation is permitted to statically initialize an object with
    > static storage duration in namespace scope (3.6.2). Otherwise such an
    > object is initialized the first time control passes through its
    > declaration; such an object is considered initialized upon the
    > completion
    > of its initialization."
    >
    > which covers the more interesting cases of static objects with
    > constructors that can be observed.
    >
    > HTH,
    > Michiel Salters
    >



    That's interesting, thanks. The the following is also correct?:


    class A
    {
    public:
    GetInt()
    {
    return myInt;
    }
    private:
    static int myInt;
    };


    you can't be sure myInt is initialised when GetInt() is called, but you
    can if you use a local static variable.

    Therefore were have:
    Singletons should always be initialised as local static objects within a
    funcion to gurantee proper initialisation.
     
    Spacen Jasset, Jan 31, 2005
    #7
    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,777
    Jason
    Dec 6, 2004
  2. Stuart MacMartin
    Replies:
    5
    Views:
    574
    Victor Bazarov
    Jul 27, 2005
  3. Replies:
    3
    Views:
    936
    Thomas Matthews
    Sep 9, 2006
  4. Dirk Bruere at NeoPax

    Threads and statics

    Dirk Bruere at NeoPax, Apr 7, 2011, in forum: Java
    Replies:
    13
    Views:
    658
  5. mohansriram

    intialisation of matrix of integers

    mohansriram, Aug 30, 2012, in forum: VHDL
    Replies:
    0
    Views:
    598
    mohansriram
    Aug 30, 2012
Loading...

Share This Page