Static initialization order fiasco

Source: Internet
Author: User
Static initialization order fiasco is a very subtle and common misunderstanding of C ++. Unfortunately, errors occur before the start of main () and are hard to be detected.

In short, suppose you have two static objects x and y in different source files X. cpp and Y. cpp. It is assumed that the constructor of the Y object will call some methods of the X object.

That's all. That's simple.

The final result is the chance that you will not be finished is 50%-50%. This is good if the Editing Unit of X. cpp is initialized first. However, if the Editing Unit of Y. cpp is initialized first, then the constructor of Y runs before the constructor of X. That is to say, the constructor of Y calls the method of the X object, and the X object is not constructed yet.

How to Prevent "static initialization order fiasco "?

By using the construct on first use method, the static object is wrapped inside the function.

For example, suppose you have two classes: Fred and Barney. There is a global Fred object named X and a global Barney object named Y. Barney's constructor calls the gobowling () method of the X object. The X. cpp file defines the X object:

// File X. cpp
# Include "Fred. HPP"
Fred X;

The Y. cpp file defines the y object:

// File Y. cpp
# Include "Barney. HPP"
Barney y;

The Barney constructor may all look like this:

// File Barney. cpp
# Include "Barney. HPP"
BARNEY: Barney ()
{
//...
X. gobowling ();
//...
}

As described above, because they are located in different source files, the probability of a disaster caused by the construction of Y before X is 50%.

There are many solutions to this problem, but a very simple solution is to replace the global Fred object X () by returning the global Function x () referenced by the Fred object.

// File X. cpp
# Include "Fred. HPP"
Fred & X ()
{
Static Fred * ans = new Fred ();
Return * ans;
}

Because static local objects are constructed only when the control flow crosses their declaration for the first time, the above new Fred () Statement will only run once: X () is called for the first time. Each subsequent call will return the same Fred object (the one pointed by ans ). Then all you need to do is change X to X ():

// File Barney. cpp
# Include "Barney. HPP"
BARNEY: Barney ()
{
//...
X (). gobowling ();
//...
}

Because this global Fred object is constructed during the first use, it is called construct on first use idiom)

The disadvantage of this method is that the Fred object will not be destructed. The C ++ FAQ book has another technique to eliminate this impact (but faces the price of "static de-initialization order fiasco ).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.