级别的静态变量获得分配/初始化?

我非常有信心,在程序开始时,全局声明的变量会被分配(并且在适用的情况下被初始化)。

int globalgarbage;
unsigned int anumber = 42;

但是在函数中定义的静态函数呢?

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

globalish分配的空间何时分配? 我猜测节目什么时候开始。 但是它是否也被初始化了? 或者当doSomething()被首次调用时它被初始化了吗?


我对此很好奇,所以我写了下面的测试程序,并用g ++版本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;
}

结果不是我所期望的。 直到第一次调用该函数时才会调用静态对象的构造函数。 这是输出:

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

来自C ++标准的一些相关的语言:

3.6.2初始化非本地对象[basic.start.init]

1

具有静态存储持续时间的对象(basic.stc.static)的存储在进行任何其他初始化之前应该被初始化(dcl.init)。 在任何动态初始化发生之前,初始化具有用常量表达式(expr.const)初始化的静态存储持续时间的POD类型(basic.types)的对象。 在同一个翻译单元中定义并动态初始化的具有静态存储持续时间的命名空间范围对象应按其定义出现在翻译单元中的顺序进行初始化。 [注意:dcl.init.aggr描述了聚合成员初始化的顺序。 本地静态对象的初始化在stmt.dcl中描述。 ]

[为编译器编写者增加更多自由的更多文本]

6.7声明声明[stmt.dcl]

...

4

所有具有静态存储持续时间的本地对象(basic.stc.static)的零初始化(dcl.init)在进行任何其他初始化之前执行。 初始化一个带有用常量表达式初始化的静态存储持续时间的POD类型的本地对象(basic.types),在它的块被首次输入之前进行初始化。 允许实现在静态存储持续时间内执行其他本地对象的早期初始化,这些条件允许实现在命名空间范围(basic.start.init)中静态存储持续时间的静态初始化对象。 否则,这样的对象在第一次通过声明时被初始化; 这样的对象在其初始化完成时被认为是初始化的。 如果通过抛出异常退出初始化,则初始化未完成,因此下一次控制进入声明时将再次尝试初始化。 如果控件在初始化对象时重新进入声明(递归),则行为是未定义的。 [例:

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

- 例子]

具有静态存储持续时间的本地对象的析构函数将在且仅当变量构造时才会执行。 [注意:basic.start.term描述了具有静态存储持续时间的本地对象被销毁的顺序。 ]


所有静态变量的内存都是在程序加载时分配的。 但是本地静态变量在第一次使用时创建和初始化,而不是在程序启动时。 这里有一些关于这方面的很好的阅读和一般的静力学。 总的来说,我认为其中的一些问题取决于实施,特别是如果你想知道这些东西将在哪里。

链接地址: http://www.djcxy.com/p/82513.html

上一篇: level static variables get allocated/initialized?

下一篇: Storage of c variables in memory