我有一个简单POD的单个实例
class A {
struct Zzz {
A* m_aPtr;
int m_val;
}
static Zzz s_zzz;
};
A::Zzz A::s_zzz;
我希望在任何其他编译单元中的任何其他静态初始化之前,s_zzz.m_aPtr和s_zzz.m_val都将被初始化为零,并且它由语言本身保证。我是对的吗?
通常我为结构提供默认构造函数。说
A::Zzz::Zzz() :
m_aPtr(0),
m_val(0)
{
}
它会创建初始化顺序问题还是引入编译器依赖项?
答案 0 :(得分:2)
至少在C ++ 0x中,您可以依赖于在任何其他初始化代码运行之前执行的所有零初始化。
从C ++ 0x FCD,[basic.start.init]
具有静态存储持续时间的变量 (3.7.1)或线程存储持续时间 (3.7.2)应为零初始化 (8.5)在任何其他初始化之前 发生了。
如果您正在考虑使用其他初始化代码中的此变量,那么显式构造函数将是一个很大的错误,因为它会在某些时候与其他初始化代码混合运行,并覆盖其他初始化程序已经进行的任何更改。
答案 1 :(得分:2)
我希望s_zzz.m_aPtr和 s_zzz.m_val将初始化为 在任何其他静态之前为零 在任何其他初始化 编译单元,它是有保证的 语言本身。
它将被初始化为零,因为它是命名空间范围内的静态生命周期变量。
零初始化在任何动态初始化之前发生(动态初始化的一个例子是当你进行一些显式初始化,或者类有一个构造函数时)。
没有定义不同翻译单元之间的零初始化顺序,但没有任何方法可以检测它或依赖它,因为它发生在其他任何事情之前,所以没关系。
重申你的观点2,你还不清楚你在问什么。
但是对于你的静态生命周期对象,效果只是它首先进行了零初始化,然后在动态初始化期间,你的构造函数被用来将其归零(尽管编译器可能足够智能以优化冗余的额外初始化)
干杯&第h。,
ERRATA :Ben Voigt提供了一个令人信服的例子,上面的最后一段是错误的。所以请不要理会。构造函数的存在意味着对象可以在更改它的操作之前,之间或之后的某个点动态初始化,从而导致相当不可预测的结果......
答案 2 :(得分:1)
无法保证编译单元之间的静态初始化顺序(参见http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14)。
如果它有构造函数,不幸的是它将不再是POD。
答案 3 :(得分:0)
当应用程序加载到内存中时,静态区域初始化为零。这是在任何代码开始执行之前。