C ++静态简单类型是按顺序初始化的吗?

时间:2010-10-15 22:37:44

标签: c++ static types

我的经验告诉我,给定一个对象:

class Object
{
private:
    static int array[];

public:
    Object(int id);
};


int Object::array[] = { 2937, 892 };


Object::Object(int id)
{
    // do something
}

array的初始化将在调用Object上的任何方法之前发生,或者在程序中的任何其他对象上调用任何方法,无论对象是否已声明static

基本上,我要问的是,是否有人不同意静态简单C类型(非对象),如charshortintlong(当在执行main()或任何其他构造函数之前将可执行文件加载到内存中时,会初始化没有由这些类型构成的构造函数的结构体吗?

5 个答案:

答案 0 :(得分:7)

是的,所有静态初始化都在调用main()之前发生。但是你无法确定初始化发生的顺序。当一个静态变量依赖于另一个静态变量的存在时,这可能会造成严重破坏。它被称为静态初始化惨败:http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14

我经常使用faq中提到的解决方案。使用内部带有静态变量的函数来更好地控制顺序。

答案 1 :(得分:7)

我认为您正在谈论的特定类型的初始化:

  

基本上,我要问的是,是否有人不同意在加载可执行文件时初始化静态简单C类型(非对象),如char,short,int和long(以及没有由这些类型组成的构造函数的结构)在调用main()或任何其他构造函数之前进入内存?

我假设您的意思是使用常量进行初始化 - 而不是通过调用函数。如果该假设是正确的,则可以确定在调用任何构造函数之前初始化将会发生:

  • 3.6.2非本地对象的初始化
  

具有静态存储持续时间的对象   (3.7.1)应为零初始化   (8.5)在任何其他初始化之前   发生了。零初始化和   用常量初始化   表达被统称为   静态初始化;所有其他   初始化是动态的   初始化。 POD类型的对象   (3.9)具有静态存储持续时间   用常量表达式初始化   (5.19)应在任何之前初始化   动态初始化发生。   对象具有静态存储持续时间   在命名空间作用域中定义的相同   翻译单位和动态   初始化应初始化   他们定义的顺序   出现在翻译单元中。

然而,如

等初始化
static int x = getvalue();

属于动态初始化类别,因此它按外观排序(并且在不同的翻译单元之间不确定)。

另一个警告是,这不适用于局部静态(在输入块之前可能不会初始化),但这确实无关紧要,因为在封闭块之前它们无法被其他任何东西访问。无论如何都进入了。

答案 2 :(得分:4)

情况确实如此。不保证的是 order ,不同翻译单元中的静态成员相互初始化。

答案 3 :(得分:2)

我想这是编译器和编译器选项相关的,但是你的编译器可能只是在编译时将值放在程序中,如果这些值是litteral(在代码中编写,如在你的例子中)。

我认为任何体面的编译器都会这样做。然后当你的exe加载到内存中时,它已经有了硬编码的值。

答案 4 :(得分:0)

标准仅表示在控制进入可以访问它们的范围之前初始化静态。它没有定义任何其他内容。我认为文件范围变量是一个不同的东西,但一般来说,使用静态和依赖静态行为是一个坏主意。