c++ - 为什么静态变量的初始化仅限于常量表达式?

标签 c++ static

来自“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/

相关文章:

c++ - 覆盖c++类中的一个方法

c++ - 如何从 c/c++ 与 Oracle eBusiness 套件通信

c++ - 如何在 for_each 期间添加元素

c++ - 使用当前焦点小部件上下文菜单自动填充菜单栏中的 "Edit"菜单

java - 静态/类变量和 GUI

具有文件范围的 C 结构体

java - Android Studio Java - 我应该使用哪个修饰符?

c++ - Borland C++ 版本 0.7 是否仍然可用?

c - 当静态变量被声明两次时会发生什么?

php - static 关键字对常量有影响吗?