什么时候初始化静态和全局变量?

C++ 中,我知道 staticglobal 对象是在 main 函数之前构造的.但是如你所知,在C中,main之前没有这种初始化过程.

In C++ I know static and global objects are constructed before the main function. But as you know, in C, there is no such kind initialization procedure before main.

例如,在我的代码中:

int global_int1 = 5;
int global_int2;
static int static_int1 = 4;
static int static_int2;

  • 这四个变量什么时候初始化?
  • 54 等初始化值在编译期间存储在哪里?初始化时如何管理?
    • When are these four variables initialized?
    • Where values for initialization like 5 and 4 are stored during compilation? How to manage them when initialization?

    • 澄清第二个问题.


      Clarification of 2nd question.

      • 在我的代码中,我使用5来初始化 global_int1,那么编译器如何assign 5global_int?例如,也许编译器首先将 5 值存储在某处(即一个表),并在初始化开始时获取该值.
      • 关于初始化时如何管理它们?",真的很模糊,我自己也不知道如何解释.有时,解释一个问题并不容易.忽略它,因为我还没有完全掌握这个问题.
      • In my code I use 5 to initialize global_int1, so how can the compiler assign 5 to global_int? For example, maybe the compiler first store the 5 value at somewhere (i.e. a table), and get this value when initialization begins.
      • As to "How to manage them when initialization?", it is realy vague and I myself does not how to interpret yet. Sometimes, it is not easy to explain a question. Overlook it since I have not mastered the question fully yet.

      推荐答案

      对于静态和全局对象,我假设您指的是具有以下特性的对象在命名空间范围内定义的静态生命周期.当这些物体是用局部作用域定义的,规则略有不同.

      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.

      形式上,C++ 分三个阶段初始化此类变量:1. 零初始化2.静态初始化3. 动态初始化该语言还区分需要动态初始化,以及那些需要静态初始化:所有静态对象(具有静态的对象生命周期)首先被零初始化,然后是具有静态的对象初始化都是初始化,然后动态初始化发生.

      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
      

      另一个近似是静态初始化是C 支持什么(对于具有静态生命周期的变量),动态其他一切.

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

      当然,编译器如何做到这一点取决于初始化,但在基于磁盘的系统上,可执行文件从磁盘加载到内存中,静态值初始化是磁盘上图像的一部分,并加载由系统直接从磁盘.在经典的 Unix 上系统,全局变量会被分成三个段":

      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":

      我怀疑很多现代系统仍在使用某些东西类似.

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

      补充说明:以上指的是C++03.对于现有程序,C++11 可能不会改变任何东西,但它确实添加 constexpr (这意味着一些用户定义的函数仍然可以是静态初始化)和线程局部变量,这开启了一个全新的蠕虫罐头.

      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.

相关文章