来自"C++ Primer,第5版“,第407页:
所有静态持续时间变量共享以下两个初始化特性:
未初始化的静态变量
常量表达式可以使用文字常量、const和enum常量以及量值运算符。下面的代码片段说明了这些要点:
int x;// x设置为0 int y= 49;// 49是常量表达式int z=2* sizeof( int ) + 1;//也是常量表达式int m=2* z;//无效,z不是常量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 14882 2003“3.6.2 (第44页):
具有静态存储持续时间(3.7.1)的
对象在进行任何其他初始化之前必须为零初始化(8.5)。
..。
允许实现以静态存储持续时间执行命名空间范围对象的初始化,即使这种初始化不需要静态地进行.
..。
最重要的一点是:
因此,如果对象(
)的初始化是指具有静态存储持续时间(可能需要动态初始化)的命名空间范围的对象( obj2 ),并且随后在同一个转换单元中定义,则未指定所使用的obj2值将是完全初始化的obj2 (因为obj2是静态初始化的)的值,还是obj2的值(仅为零初始化)。
关于这类问题的进一步解读:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
编辑:填上答案。酒吧是正确的答案(并被接受),但我真的错过了“作为一个结果..。”部分。此外,我认为我添加的链接可能是有用的。
发布于 2011-12-06 13:59:04
静态初始化(技术上是常量初始化)需要常量表达式,但是静态存储持续时间变量不需要。
int x; // 0 initialized
int y = 49; // statically initialized
int z = 2 * sizeof(int) + 1; // statically initialized
int m = 2 * z; // dynamically or statically initialized3.6.2将零初始化和常量初始化一起称为静态初始化;所有其他初始化都是动态初始化。静态初始化应在进行任何动态初始化之前执行。
动态初始化可以依赖于在编译时无法确定的函数和其他事情。如果编译器能够确定结果,则允许它执行静态初始化。
您发布的示例将有效,尽管它可能会给更复杂的初始化带来麻烦,因为可以动态或静态地初始化一些变量:
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发布于 2011-12-06 13:44:15
z被初始化为2 * sizeof(int) + 1,但以后可以更改为另一个值。通过将const表达式作为初始化器的明确要求,可以清楚地看到您将得到什么值。如果允许非常量表达式,则可能会根据初始化顺序得到不同的值。有了const的要求,你得到了什么就很清楚了。
发布于 2011-12-06 14:21:12
引用的文本是完全错误的,而且一直是错误的。静态变量可以用您想要的任何表达式初始化(前提是表达式本身是合法的,并且不使用其他尚未初始化的变量)。比如:
int i = f();非常频繁,即使在名称空间范围内也是如此,当然,带有类类型和用户定义构造函数的静态变量甚至更频繁。
https://stackoverflow.com/questions/8400791
复制相似问题