Static Initialization Order Fiasco - Local Static's Initialization

Hi,

I'm reading Scott Myers 'Effective C++' at the moment and using Herbert Schildt's 'C++ The Complete Reference (3rd Edition)' as a backup reference.

In Effective C++ Myers discusses in Item 4 the "order of intialization of non-local static objects defined in different translation units". This seems to be the same problem called by the C++ Faq Lite the "static order intialization fiasco":

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

The solution suggested in both cases is to move each non-local static object into its own function, where it's declared static and have the function return a reference to its enclosed local static object.

Scott Myers says: "This approach is founded on C++'s guarantee that local static objects are intiialized when the object's definition is first encountered during a call to that function." ... "As a bonus, if you never call a function emulating a non-local static object, you never incur the cost of constructing and destructing the object."

C++ Faq Lite calls the solution the Construct On First Use idiom and says "Since static local objects are constructed the first time control flows over their declaration (only) ..."

In Herbert Schildt's C++ The Complete Reference (3rd Edition) Chapter 2 (Pg. 31) on Variable Initializations he says: "Global and static local variables are initialized only at the start of the programs".

Is there a discrepancy between when static local built in types get initialised versus when static local user defined types get initialised or how can Herb Schildt's statement above be reconciled with those quoted from Scott Myers and the C++ Faq Lite?
Oh, have a look at:

http://catb.org/jargon/html/B/bullschildt.html

Further reading, related to static initialization + threading, that you may find interesting;

http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx
Meyers says that:

1
2
3
4
5
6
7
8
9
std::string foo() {
    static std::string s1( "Hello" );
    return s1;
}

std::string bar() {
    static std::string s2( "World" );
    return s2;
}


the order in which s1 and s2 are constructed depends upon the order in which foo() and bar() are called.

Schildt says that

1
2
static std::string s1( "Hello" );
static std::string s2( "World" );


the order in which s1 and s2 are constructed, if s1 and s2 are in the same .cpp file (translation unit), is
the order in which they are declared in the file. if s1 and s2 are in different translation units, then the
order in which they are constructed is undefined by the standard.

You can regain control over construction order by placing the static globals inside functions and then
calling the functions in the order you want them initialized.

Topic archived. No new replies allowed.