C++: static on static member variable dependent initialization with int vs struct

后端 未结 1 1815
野的像风
野的像风 2021-01-02 13:54

Given a static member variable which is initialized from a static member variable of another class, the non-literal struct ii is sometimes default init

相关标签:
1条回答
  • 2021-01-02 14:29

    Congratulations! You've encountered the static initialization order fiasco.

    The initialization order of static objects is not defined across multiple translation units.

    StaticClass::ii is defined in ONE.cpp and ABC::def_ii is defined in abc.cpp. Therefore StaticClass::ii may or may not be initialized before ABC::def_ii. Since the initialization of ABC::def_ii uses the value of StaticClass::ii the value will depend on whether StaticClass::ii was initialized yet.

    The initialization order of static objects within a translation unit is defined. Objects are initialized in the order in which they are defined. Therefore when you concatenate the source files, the order of initialization is defined. However, when you concatenate the files in the wrong order, the defined initialization order is wrong:

    const OneI ABC::def_ii = StaticClass::ii; // StaticClass::ii wasn't initialized yet
    const OneI StaticClass::ii = OneI{333};
    

    Can this be avoided somehow by enforcing the latter ordering all the time?

    Most trivial solution is to define both objects in the same translation unit, in the correct order. A more general solution is to initialize your static objects using Construct On First Use Idiom.

    Is using a static pointer in ABC to StaticClass::ii safe (I'd prefer not to, though)?

    As long as the dereferenced value of the pointer isn't used during the initialization of a static object in another translation unit that where the pointed object is defined, yes, replacing ABC::def_ii with a pointer would be safe.


    StaticClass::ii will have been zero-initialized during the static initialization phase††. The Static initialization order fiasco concerns the dynamic initialization phase††.

    †† C++ standard draft [basic.start.static]

    If constant initialization is not performed, a variable with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) is zero-initialized ([dcl.init]). Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place. [ Note: The dynamic initialization of non-local variables is described in [basic.start.dynamic]; that of local static variables is described in [stmt.dcl]. — end note ]

    0 讨论(0)
提交回复
热议问题