2014-02-25 33 views
1

这是安全的假设初始化B和C这里时A被初始化为1?初始化静态常量成员变量的基础上相互

struct Test { 
    static const int A = 1; 
    static const int B = A + 1; 
    static const int C = B + 1; 
}; 

int main() { 
    printf("%i %i %i\n", Test::A, Test::B, Test::C); ==> 1 2 3 
} 

有关非整静态成员

struct Test2 { 
    constexpr static const Test A = Test(); 
    constexpr static const Test B = A; 
    constexpr static const Test C = B; 
}; 

clang-Wall问题没有任何警告的内容。

回答

3

它们将在给定的翻译单元中以及任何其他对象或变量之前按照定义的顺序进行初始化。

+0

如果他们在不同的翻译单位定义? (实际上,在这种情况下,由于只有静态初始化参与,它是安全的,无论配置,但你有关于一般情况下是正确的。) –

+0

@JamesKanze是的 - 这是一个正确的 –

+0

@JamesKanze如果他们在不同的翻译单元中定义的初始化顺序是不可预知的。参见“静态初始化失败”:http://www.parashift.com/c++-faq/static-init-order.html – jaho

2

也许吧。在这种情况下,A的初始化是静态的,因此可以使用 A作为整型常量表达式。然后 传播到B。当你声明的成员,他们将 静态初始化,什么编译器已经评估(即 01),该计划甚至开始之前。

如果他们没有静态初始化(这是只有在法律 C++ 11),不管是什么,然后他们将在定义出现在源文件中的顺序初始化 ,如果他们 任何理由在相同的源文件中定义。如果它们未在 中定义相同的源文件,则它们初始化的顺序是未指定的 。

关于你的第二个例子:如果他们真的constexpr, 仍然只有涉及常量表达式,因此 一切都将在编译时决定,并且成员将 被静态初始化。

0

是的。具有静态存储期的对象始终是之前什么都初始化为零:

变量与静态存储时间(3.7.1)或线程存储时限(3.7.2)应是零初始化(8.5)之前的任何其他初始化发生。

[3.6.2§2]

因此任何恒定的或动态的初始化可以假设具有静态存储持续时间的所有其他对象是至少零初始化。

请注意,这不是不是给零任何初始化以外的任何保证!

+0

但他的例子中没有动态初始化。 –

+0

我详细阐述了一下,它只是花了一秒钟才得到正确的措词;) –

相关问题