When are static and global variables initialized?

By static and global objects, I presume you mean objects with
static lifetime defined at namespace scope. When such objects
are defined with local scope, the rules are slightly different.

Formally, C++ initializes such variables in three phases:
1. Zero initialization
2. Static initialization
3. Dynamic initialization
The language also distinguishes between variables which require
dynamic initialization, and those which require static
initialization: all static objects (objects with static
lifetime) are first zero initialized, then objects with static
initialization are initialized, and then dynamic initialization
occurs.

As a simple first approximation, dynamic initialization means
that some code must be executed; typically, static
initialization doesn’t. Thus:

extern int f();

int g1 = 42;    //  static initialization
int g2 = f();   //  dynamic initialization

Another approximization would be that static initialization is
what C supports (for variables with static lifetime), dynamic
everything else.

How the compiler does this depends, of course, on the
initialization, but on disk based systems, where the executable
is loaded into memory from disk, the values for static
initialization are part of the image on disk, and loaded
directly by the system from the disk. On a classical Unix
system, global variables would be divided into three “segments”:

text:
The code, loaded into a write protected area. Static
variables with `const` types would also be placed here.
data:
Static variables with static initializers.
bss:
Static variables with no-initializer (C and C++) or with dynamic
initialization (C++). The executable contains no image for this
segment, and the system simply sets it all to `0` before
starting your code.

I suspect that a lot of modern systems still use something
similar.

EDIT:

One additional remark: the above refers to C++03. For existing
programs, C++11 probably doesn’t change anything, but it does
add constexpr (which means that some user defined functions
can still be static initialization) and thread local variables,
which opens up a whole new can of worms.

Leave a Comment