来自“C++ Primer,第 5 版”,第 407 页:
All static duration variables share the following two initialization features:
An uninitialized static variable has all its bits set to 0.
A static variable can be initialized only with a constant expression.
A constant expression can use literal constants, const and enum constants, and the sizeof operator. The following code fragment illustrates these points:
int x; // x set to 0 int y = 49; // 49 is a constant expression int z = 2 * sizeof(int) + 1; // also a constant expression int m = 2 * z; // invalid, z not a constant int main() {...}
我的问题是 - 为什么这是标准?这样做的(实际)原因是什么。
否则会有什么伤害降临到我们身上?
特别是,我发现很难找到无效的理由:
int m = 2 * z;//无效,z 不是常量
因为 z
本身在编译时是已知的。
答案:
简单地说,根据标准,不保证main
第一条语句之前的指令会按顺序执行。
但可以保证所有静态存储在任何其他初始化之前都将被零初始化。
这意味着在我给出的示例中:int m = 2 * z;
是一个未定义的行为,m 可能评估为 2*0=0
或者它可能被评估到 `2*(2 * sizeof(int) + 1).
出自“C++ 标准 - ANSI ISO IEC 14882 2003”3.6.2(第 44 页):
Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place.
...
An implementation is permitted to perform the initialization of an object of namespace scope with static storage duration as a static initialization even if such initialization is not required to be done statically...
...
重要的一点:
As a consequence, if the initialization of an object obj1 refers to an object obj2 of namespace scope with static storage duration potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was statically initialized) or will be the value of obj2 merely zero-initialized.`
进一步阅读此类问题:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
编辑:输入答案。 Pubby 的答案是正确的(并被接受了),但我真的错过了“因此……”部分。另外,我认为我添加的链接可能会有用。
最佳答案
静态初始化(技术上常量初始化)需要常量表达式,但静态存储持续时间变量不需要。
int x; // 0 initialized
int y = 49; // statically initialized
int z = 2 * sizeof(int) + 1; // statically initialized
int m = 2 * z; // dynamically or statically initialized
3.6.2 Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.
动态初始化可以依赖于函数和其他无法在编译时决定的东西。如果可以确定结果,则允许编译器执行静态初始化。
您发布的示例将起作用,尽管它可能会导致更复杂的初始化出现问题,因为某些变量可以动态或静态初始化:
inline double fd() { return 1.0; }
extern double d1;
double d2 = d1; // unspecified:
// may be statically initialized to 0.0 or
// dynamically initialized to 1.0
double d1 = fd(); // may be initialized statically to 1.0
关于c++ - 为什么静态变量的初始化仅限于常量表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8400791/