我的经验告诉我,给定一个对象:
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类型(非对象),如char
,short
,int
和long
(当在执行main()或任何其他构造函数之前将可执行文件加载到内存中时,会初始化没有由这些类型构成的构造函数的结构体吗?
答案 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.7.1)应为零初始化 (8.5)在任何其他初始化之前 发生了。零初始化和 用常量初始化 表达被统称为 静态初始化;所有其他 初始化是动态的 初始化。 POD类型的对象 (3.9)具有静态存储持续时间 用常量表达式初始化 (5.19)应在任何之前初始化 动态初始化发生。 对象具有静态存储持续时间 在命名空间作用域中定义的相同 翻译单位和动态 初始化应初始化 他们定义的顺序 出现在翻译单元中。
然而,如
等初始化static int x = getvalue();
属于动态初始化类别,因此它按外观排序(并且在不同的翻译单元之间不确定)。
另一个警告是,这不适用于局部静态(在输入块之前可能不会初始化),但这确实无关紧要,因为在封闭块之前它们无法被其他任何东西访问。无论如何都进入了。
答案 2 :(得分:4)
情况确实如此。不保证的是 order ,不同翻译单元中的静态成员相互初始化。
答案 3 :(得分:2)
我想这是编译器和编译器选项相关的,但是你的编译器可能只是在编译时将值放在程序中,如果这些值是litteral(在代码中编写,如在你的例子中)。
我认为任何体面的编译器都会这样做。然后当你的exe加载到内存中时,它已经有了硬编码的值。
答案 4 :(得分:0)
标准仅表示在控制进入可以访问它们的范围之前初始化静态。它没有定义任何其他内容。我认为文件范围变量是一个不同的东西,但一般来说,使用静态和依赖静态行为是一个坏主意。