When are function level static variables obtained / initialized?

I am sure that globally declared variables will get highlighted (and initialized, if applicable) at program startup.

int globalgarbage; unsigned int anumber = 42; 

But what about static defined within a function?

 void doSomething() { static bool globalish = true; // ... } 

When is space allocated for globalish ? I guess when the program starts. But is it also initialized? Or is it initialized the first time doSomething() called?

+79
c ++ c variables
Sep 10 '08 at 23:49
source share
7 answers

I was interested, so I wrote the following test program and compiled it using g ++ version 4.1.2.

 include <iostream> #include <string> using namespace std; class test { public: test(const char *name) : _name(name) { cout << _name << " created" << endl; } ~test() { cout << _name << " destroyed" << endl; } string _name; }; test t("global variable"); void f() { static test t("static variable"); test t2("Local variable"); cout << "Function executed" << endl; } int main() { test t("local to main"); cout << "Program start" << endl; f(); cout << "Program end" << endl; return 0; } 

The results were not what I expected. The constructor for the static object was not called until the first function call. Here is the result:

 global variable created local to main created Program start static variable created Local variable created Function executed Local variable destroyed Program end local to main destroyed static variable destroyed global variable destroyed 
+78
Sep 11 '08 at 0:18
source share

Some relevant language from the C ++ standard:

3.6.2 Initialization of non-local objects [basic.start.init]

one

Storage for objects with static storage duration (basic.stc.static) must be zero initialized (dcl.init) before any other initialization. Objects POD types (basic.types) with static storage duration initialized by constant expressions (expr.const) must be initialized before any dynamic initialization begins. Namespace scope objects with static storage duration defined in the same translation unit and dynamically initialized are initialized in the order in which their definition appears in the translation unit. [Note: dcl.init.aggr describes the order in which aggregate elements are initialized. initialization of local static objects is described in stmt.dcl. ]

[more text below adding more freedoms for compiler authors]

6.7 Declaration of declaration [stmt.dcl]

...

four

Zero initialization (dcl.init) of all local objects with a static storage duration (basic.stc.static) is performed before any other initialization takes place. Local object Type POD (basic.types) with a static storage duration is initialized with constant expressions, initialized before the block is first entered. An implementation is allowed to perform early initialization of other local objects with a static duration storage under the same conditions that an implementation is allowed to statically initialize an object with a static duration storage in the namespace (basic.start.init). Otherwise, the object is initialized, the first control passes through its expression; such an object is considered initialized to complete its initialization. If the initialization completes the exception, the initialization is not completed, so it will try again again the next time the control enters the declaration. If the control re-enters the declaration (recursively) while the object is initialized, the behavior is undefined. [Example:

  int foo(int i) { static int s = foo(2*i); // recursive call - undefined return i+1; } 

- end of example]

5

A destructor for a local object with a static storage duration will be executed if and only if the variable was built. [Note: basic.start.term describes the order in which local objects with static storage duration are destroyed. ]

+47
Sep 12 '08 at 12:20
source share

Memory for all static variables is allocated when the program loads. But local static variables are created and initialized the first time they are used, and not when the program starts. There is a good read about it and statics in general here . In general, I think that some of these problems are implementation dependent, especially if you want to know where these materials will be located in memory.

+23
Sep 11 '08 at 0:41
source share

The compiler will highlight the static variable (s) defined in the foo function when the program loads, however, the compiler will also add some additional instructions (machine code) to your foo function so that the first time this additional code is called, it will initialize the static variable (for example, by calling the constructor if applicable).

@Adam: This backstage injection of code by the compiler is the reason you saw it.

+9
Sep 11 '08 at 1:00
source share

I'm trying to check the code again with Adam Pierce and added two more cases: a static variable in the class and a POD type. My compiler is g ++ 4.8.1, on Windows (MinGW-32). Result - the static variable in the class is treated the same as the global variable. Its constructor will be called before entering the main function.

  • Conclusion (for g ++, Windows environment):

    • Global variable and static member in the class : the constructor is called before the main function (1) is entered .
    • Local static variable : the constructor is called only when execution reaches its declaration for the first time.
    • If the Local static variable is a POD type , then it is also initialized before entering the main function (1) . An example for the POD type: static number int = 10;

(1) : The correct state must be: "before any function from the same translation unit is called." However, for simple, as in the example below, this is the main function.

include <iostream>

 #include < string> using namespace std; class test { public: test(const char *name) : _name(name) { cout << _name << " created" << endl; } ~test() { cout << _name << " destroyed" << endl; } string _name; static test t; // static member }; test test::t("static in class"); test t("global variable"); void f() { static test t("static variable"); static int num = 10 ; // POD type, init before enter main function test t2("Local variable"); cout << "Function executed" << endl; } int main() { test t("local to main"); cout << "Program start" << endl; f(); cout << "Program end" << endl; return 0; } 

result:

 static in class created global variable created local to main created Program start static variable created Local variable created Function executed Local variable destroyed Program end local to main destroyed static variable destroyed global variable destroyed static in class destroyed 

Has anyone tested on Linux env?

+5
Dec 03 '13 at 15:49
source share

Static variables are allocated inside the code segment - they are part of the executable image and therefore are displayed in the already initialized one.

Static variables within the scope are handled the same way, scope is only a language level construct.

For this reason, you are guaranteed that the static variable will be initialized to 0 (unless you specify something else), and not the undefined value.

There are several other aspects for initialization that you can use: for example, shared segments allow you to run multiple instances of an executable file at once to access the same static variables.

In C ++ static objects (globally), their constructors are called part of the program run under the C runtime library. In Visual C ++, at least the order in which objects are initialized can be controlled using init_seg pragma.

+3
Sep 10 '08 at 23:54
source share

Or is it initialized the first time doSomething () is called?

Yes it is. This, in particular, allows you to initialize global data structures when appropriate, for example inside try / catch blocks. For example. instead

 int foo = init(); // bad if init() throws something int main() { try { ... } catch(...){ ... } } 

You can write

 int& foo() { static int myfoo = init(); return myfoo; } 

and use it inside the try / catch block. At the first call, the variable will be initialized. Then, on the first and next calls, its value will be returned (by reference).

+3
Sep 11 '08 at 5:58
source share



All Articles