Initialising global object arrays that are used "extern"

Discussion in 'C++' started by Christoph Conrad, Mar 1, 2007.

  1. Hi,

    given the following test case, with CString from Microsofts MFC:

    ==================================================
    file 1:

    CString arr[100];

    ==================================================
    file 2:

    extern CString arr[];


    void somefunc()
    {
    arr[0] = "foo";
    arr[1] = "bar";
    }
    ==================================================

    It does not seem to be guaranteed that arr is initialised correctly
    before usage. Is there some trick to force this?

    Best regards,
    Christoph
     
    Christoph Conrad, Mar 1, 2007
    #1
    1. Advertising

  2. Christoph Conrad wrote:
    > Hi,
    >
    > given the following test case, with CString from Microsofts MFC:
    >
    > ==================================================
    > file 1:
    >
    > CString arr[100];
    >
    > ==================================================
    > file 2:
    >
    > extern CString arr[];
    >
    >
    > void somefunc()
    > {
    > arr[0] = "foo";
    > arr[1] = "bar";
    > }
    > ==================================================
    >
    > It does not seem to be guaranteed that arr is initialised correctly
    > before usage. Is there some trick to force this?


    Unless 'somefunc' is called from a static object's constructor, you
    don't have a problem. Objects with static storage duration (and the
    global objects like your 'arr' have static storage duration) are
    constructed before 'main' is called, and your 'somefunc' is supposedly
    called after 'main' (probably while 'main' is executing).

    If, in fact, 'somefunc' *is* called from another static object's c-tor,
    then you may have a problem usually called "static object initialisation
    order fiasco". To overcome that you might introduce a flag of sorts.
    We know that initialisation within the same module happens in the order
    of declarations, so if you define a static bool right after 'arr' in
    the same module where 'arr' is defined, and make it *dynamically*
    initialised (by calling a function) to 'true', you can then check the
    value of that bool in the other module and then see if it's been already
    set to 'true' (it is set to 'false' before any initialisation). Do not
    use the 'arr' if the flag is 'false'... In order to have 'arr' ready
    when some other static object is being constructed, you need to place
    the other object in the same module as 'arr', after 'arr'.

    Another way is not to have 'arr' exposed, but instead have a function
    that would return elements of 'arr', like so

    CString& arrAt(size_t i) {
    static CString arr[100];
    assert(i < 100);
    return arr;
    }

    and use it instead of indexing the array itself. That ensures that
    the array is initialised upon the first call to the function.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 1, 2007
    #2
    1. Advertising

  3. Hi Victor,

    thank you for your detailed answer. So it must be another problem in our
    program.

    Best regards,
    Christoph
     
    Christoph Conrad, Mar 1, 2007
    #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. Thomas Matthews
    Replies:
    5
    Views:
    2,553
    tom_usenet
    Aug 2, 2004
  2. Problem Initialising char arrays

    , Nov 14, 2005, in forum: C Programming
    Replies:
    2
    Views:
    1,878
    Mark McIntyre
    Nov 14, 2005
  3. Philipp
    Replies:
    21
    Views:
    1,188
    Philipp
    Jan 20, 2009
  4. Alex Vinokur
    Replies:
    3
    Views:
    512
    Zoltan Juhasz
    Jun 15, 2012
  5. Andre
    Replies:
    5
    Views:
    565
    Keith Thompson
    Jul 17, 2012
Loading...

Share This Page