c ++静态POD初始化

时间:2010-12-07 14:09:18

标签: c++ static initialization pod

我有一个简单POD的单个实例

a.hpp

class A {
    struct Zzz {
        A*  m_aPtr;
        int m_val;
    }

    static Zzz s_zzz;
};

a.cpp

A::Zzz A::s_zzz;

我希望在任何其他编译单元中的任何其他静态初始化之前,s_zzz.m_aPtr和s_zzz.m_val都将被初始化为零,并且它由语言本身保证。我是对的吗?

通常我为结构提供默认构造函数。说

A::Zzz::Zzz() :
 m_aPtr(0),
 m_val(0)
{
}

它会创建初始化顺序问题还是引入编译器依赖项?

4 个答案:

答案 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)

  1. 无法保证编译单元之间的静态初始化顺序(参见http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14)。

  2. 如果它有构造函数,不幸的是它将不再是POD。

答案 3 :(得分:0)

  1. 静态数据始终初始化为零。
  2. 不,它不应该引入任何初始化问题。
  3. 当应用程序加载到内存中时,静态区域初始化为零。这是在任何代码开始执行之前。