【发布时间】:2011-12-06 13:38:00
【问题描述】:
来自“C++ Primer,第 5 版”,第 407 页:
所有静态持续时间变量共享以下两个初始化 特点:
未初始化的静态变量的所有位都设置为 0。
静态变量只能用常量表达式初始化。
常量表达式可以使用文字常量、const 和 enum 常量和 sizeof 运算符。下面的代码片段 说明以下几点:
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; // invalid, z not a constant
因为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 页):
具有静态存储持续时间(3.7.1)的对象应为零初始化 (8.5) 在任何其他初始化发生之前。
...
一个实现被允许执行一个初始化 具有静态存储持续时间的命名空间范围的对象作为静态 初始化,即使不需要进行此类初始化 静态...
...
还有最重要的一点:
因此,如果对象 obj1 的初始化引用了 具有静态存储持续时间的命名空间范围的对象 obj2 可能需要动态初始化并在后面定义 相同的翻译单元,未指定obj2的值是否 used 将是完全初始化的 obj2 的值(因为 obj2 是 静态初始化)或将只是 obj2 的值 零初始化。`
进一步阅读此类问题:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
编辑:输入答案。 Pubby's 是正确的答案(并被接受),但我真的错过了“结果......”部分。另外,我认为我添加的链接可能有用。
【问题讨论】:
-
你用的是什么编译器?像这样的例子对我来说编译得很好。
-
您可能会混淆“静态变量”和“静态初始化”的不同概念。静态变量可以静态或动态初始化。