Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does "static initialization" mean?

Tags:

c++

c++11

I've been reading up on PODs in C++11, and several of the places I've read have said something about PODs supporting static initialization. For example:

On StackOverflow:

The idea of a POD is to capture basically two distinct properties:
1. It supports static initialization, and
2. Compiling a POD in C++ gives you the same memory layout as a struct compiled in C.

(only the bolded part is relavent)

On Wikipedia:

A type that is trivial can be statically initialized.

Apparently I'm not understanding what static initialization is. I thought making a global variable was an example of static initialization, but I can do the following and yet Foo isn't a POD:

#include <type_traits>
#include <iostream>

struct Foo {
  Foo() : x(0), y(0) {}
  int x;
  int y;
};

struct Bar {
  Bar() = default;
  int x;
  int y;
};

// Apparently the following two lines are not "static initialization" because
// Foo is non-POD yet we can still do this:
Foo f;
Bar b;

int main()
{
    if (std::is_pod<Foo>::value) std::cout << "Foo is a POD" << std::endl;
    else                         std::cout << "Foo is *not* a POD" << std::endl;

    if (std::is_pod<Bar>::value) std::cout << "Bar is a POD" << std::endl;
    else                         std::cout << "Bar is *not* a POD" << std::endl;
}

Output:

Foo is *not* a POD
Bar is a POD

So what exactly is static initialization, and how does it relate to trivial classes? Examples would be awesome.

like image 807
Cornstalks Avatar asked Dec 11 '22 17:12

Cornstalks


2 Answers

Static initialization is initialization of some variable with a compile-time value such that the value ends up being "baked into" the executable image (no code needs to be actually run):

struct Foo {
  int x;
  int y;
};

Foo foo = { 0, 1 };

In the above example struct Foo is POD, so the compiler knows that its memory layout is just two integers next to each other. It also knows that foo.x should be initialized to 0 and foo.y to 1. This is enough information to produce a "memory image" of how foo should look at compile time and write it into the executable image.

When the image is later run, the OS loader maps its contents to a memory address and in this way makes foo "alive". The important thing is that the "initialization" of foo has actually completed before the process (which includes your code and also code from the C/C++ runtimes, which get to run first) has had time to execute even a single CPU instruction.

like image 151
Jon Avatar answered Dec 28 '22 01:12

Jon


Initialization of objects with static duration is divided in two passes, static initialization and dynamic initialization (note the abuse of the term static :)).

Dynamic initialization refers to initialization that involves calling functions, and thus must take place at runtime, compared with initialization from literals that can be stored in the executable itself and just loaded.

like image 42
David Rodríguez - dribeas Avatar answered Dec 28 '22 02:12

David Rodríguez - dribeas