When are static members of a C ++ class initialized?

There seems to be no easy answer to this, but are there any assumptions that can be safely made when you can access the field of a static class?

EDIT: The only safe assumption is that all statics are initialized before the program starts (call main ). So, until I refer to the statics from another static initialization code, I have nothing to worry about?

+52
c ++ initialization static
Sep 14 '09 at 13:51
source share
7 answers

The standard guarantees two things: objects defined in the same translation unit (usually this means a .cpp file) are initialized in the order of their definitions ( not declarations ):

3.6.2

Storage for objects with a static storage duration (basic.stc.static) must be initialized to zero (dcl.init) before any other initialization. Zero initialization and constant expression initialization are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD types (basic.types) with a static storage duration, initialized with constant expressions (expr.const), must be initialized before any dynamic initialization begins. Objects with a static storage duration defined in the namespace area in the same translation system and dynamically initialized must be initialized in the order in which their definition appears in the translation block.

Another guaranteed thing is that the initialization of static objects from a translation unit will be performed before using any object or function from this translation unit:

It is determined by the implementation whether the dynamic initialization (dcl.init, class.static, class.ctor, class.expl.init) of the namespace object is performed before the first statement of main. If initialization is delayed until some point after the first statement of main, it must occur before the first use of any function or object defined in the same translation unit as the object to be initialized.

Nothing else is guaranteed (especially the order of initialization of objects defined in different translation units is determined by the implementation).

<y> EDIT As stated in Suma's comment, it is also guaranteed that they are initialized before entering main .

+46
Sep 14 '09 at 14:07
source share

They are initialized before the program starts (i.e., before main entered).

If there are two or more definitions (static data) in one CPP file, they are initialized in the sequence in which they are defined in the file (the one that was defined earlier / above in the file was initialized until the next).

If there are two or more definitions (static data) in more than one CPP file, the sequence in which the CPP files are processed is undefined / specific-specific. This is a problem if the global variable constructor (called before the program starts) refers to another global variable defined in another CPP file that may not have been created yet. However, paragraph 47 of Meyers' Effective C ++ (which is called "Make sure that global objects are initialized before they are used") describes a description of the workflow ...

  • Define a static variable in the header file (it is static, so you can have multiple instances of it without a complainer)

  • Ask the constructor of this variable to call everything you need (in particular, build global singletones declared in the headers)

... which, he said, is a technique that can be used in some system header files, for example. so that the cin global variable is initialized before the static variable constructors use it.

+17
Sep 14 '09 at 14:01
source share

Your final conclusion in the editor is correct. But the problem is the class stats themselves. It’s easier to say that my code will have static class elements that are not related to other global data elements / static class, but as soon as you take this route, everything will be wrong soon. One of the approaches that I found useful in practice is not to have static elements of a class class, except for the methods of the static shell of the class. These methods can then hold a static object within themselves. E.g.

 TypeX* Class2::getClass1Instance() { static TypeX obj1; return &obj1; } 

Code> Note. An earlier answer says:

Another guaranteed thing is that the initialization of static objects from a translation unit will be performed before using any object or function from this translation unit

This is not entirely correct, and the default value is incorrectly displayed here. This may be invalid if the function from the translation unit is called before entering the main one.

+3
Jul 22 '15 at 9:49
source share

They can be initialized in implementation file files (.c / cpp / cc). Do not initialize them in .h, as the compiler will complain about several definitions.

Usually they are initialized before the main one, but the order is indicated, therefore, it avoids the dependencies. They can certainly be accessed as part of a member function. Keep in mind the initialization order is unknown for static members. I would suggest encapsulating a static member in a static function that will check if an element has been initialized.

+1
Sep 14 '09 at 13:58
source share

I believe that it can be obtained at any time during execution. The undefined order of initialization of static variables remains.

0
Sep 14 '09 at 13:57
source share

There is no absolutely trivial answer to this question, but basically they are initialized immediately before control is transferred to the entry (main) point of your program. The order in which they are initialized is (to my knowledge) undefined and may be specific to the compiler.

EDIT: To clarify, your added assumption is correct. As long as you only access it after the main login, you do not need to worry about when / how to initialize it. By this time it will be initialized.

0
Sep 14 '09 at 13:57
source share

I think the main thread of the process will follow these five steps in order

  • CRT library initialization

  • static initialization

  • execution of main () function

  • static unification

  • CRT library unification

Do you want to use static statics from another static initialization code? The following codes may work:

 class A; static auto_ptr<A> a(auto_ptr<A>(&GetStaticA())); A &GetStaticA(void) { static A *a = NULL; //the static basic type variables initialized with constant experession will be initialized earlier than the other static ones if (a == NULL) { a = new A(); return *a; } } 
-one
Sep 14 '09 at 14:57
source share



All Articles