When and how are static data initialized in C++?

2019-07-15 12:09发布

When are static data initialized ?

I think:

It can be initialized by constructor,

or

when it is declared,

or outside of the class by

class A::member_d = 5; //  member_d is static  

others ?

Also, When do file scope static variables initialized and when do function scope static variables initizliaed?

I think they are initialized when they are declared.

thanks

4条回答
Rolldiameter
2楼-- · 2019-07-15 12:37

Static Storage duration object initialization:

Note: Static member objects are initialized the same way as objects at file scope.

  • Objects at file scope are initialized at point of definition.
    • You can think of these as all being initialized before main() is called.
    • See details below.
  • Objects in function scope are initialized the first time execution passes over the definition.
    • ie Usually the first time the function is called.

The object is initialized by the initializer in the definition. if you do not provide an initializer then it will be zero-initialized.

int x1;        // zero initialized.
int x2 = 5;    // initialized with 5 
A   y1;        // Default initialized:
               // If A has a user defined constructor this is called.
               // If A has a compiler generated constructor then
               // it is value-initialized which means class objects have their
               // default constructor called and POD objects are zero-initialized
A   y2 = A();  // Default constructed.
A   y3(5);     // Constructor called with value 5.

Static members are exactly the same as objects as file scope.

class Z
{
    static int x1; // declaration;
    static int x2;
    static A   y1;
    static A   y2;
    static A   y3;
};
// definition

int Z::x1;
int Z::x2 = 5;
A   Z::y1;
A   Z::y2 = A();
A   Z::y3(5);

Now the order that they are initialized is harder to define. The order is deliberately left vague to allow for compiler and linker situations that the committee could not foresee.

It is defined in:

3.6.2 Initialization of non-local variables

The main thing to note is:

Non-local variables with static storage duration are initialized as a consequence of program initiation.

So in most situations they will all be fully constructed before main is entered.

As noted by others. The compiler is allowed to delay initialization.

3.6.2 Paragraph 4

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main.

This addition is mainly done to support dynamically loading libraries at runtime (which may by laded dynamically after main has started). But it does provide a simple guarantee that all static storage duration objects within a compilation until will be fully constructed before any objects or function in that compilation are used.

3.6.2 Paragraph 5

If the initialization is deferred to some point in time after the first statement of the initial function of the thread, it shall occur before the first odr-use (3.2) of any variable with thread storage duration defined in the same translation unit as the variable to be initialized.

查看更多
Explosion°爆炸
3楼-- · 2019-07-15 12:38

Static members of a class are initialized at the point of definition. Const integral data types are an exception that can be initialized at the point of declaration. When such initialization is going to be executed is somewhat complicated (google for static initialization fiasco). According to the standard:

If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized.

查看更多
等我变得足够好
4楼-- · 2019-07-15 12:42

Global variables are initialized at program start-up, before main() is invoked. Static objects that are local to a scope are initialized the first time execution passes over them.

Static class members are just global variables, so see above.

Destruction of global and static objects happens after main() returns.

(The implementation details of this are fairly intricate, since all the destructors have to be queued up for execution somewhere, and for local statics there needs to be a flag to indicate whether the object has already been instantiated.)

查看更多
地球回转人心会变
5楼-- · 2019-07-15 12:51

No, of course, the constructor can't initialize static data members. For const integral or enumeration types, you can initialize within the scope of the class definition. However, in general, you must initialize outside the class definition.

查看更多
登录 后发表回答