命名空间范围变量的 C++ 初始化

C++ initialization of namespace scope variable

考虑以下程序:(查看现场演示 here.

#include <iostream>
inline double fun()
{
    return 3.0;
}
extern double m;
double d2=m;
int main()
{
    std::cout<<d2;
}
double m=fun();

我原本希望程序输出为 3.0,但它给了我输出 0。为什么?

看起来变量 d2 是静态初始化的?

不是应该动态初始化吗?

我已经在 g++ 4.8.1、4.9.2 和 MSVS 2010 上对其进行了测试,并得到 0 作为输出。

是的,d2m 都有静态存储持续时间,因为它们是在命名空间范围内声明的,未修饰的。

这意味着它们是 零初始化 作为任何其他初始化发生之前的第一步。然后,d2 设置为 m。直到 之后, m 变成了 3.0

考虑以下内容,它们本质上是同一件事:

int main()
{
   int x = 0, y = 0;
   y = x;
   x = 3;
}

显然,在这里,期望 y 等于 3 是无稽之谈,但这就是你在做的事情。

如果您希望初始化像函数-static 变量那样发生,而初始化在首次使用时发生(有点),那您就错了。

C++ 文件中的变量从上到下初始化。所以m是在d之后初始化的。

还有其他一些细微之处。

当编译器可以解决它时,它有时会发出变量的数据定义 - 将值设置为已知常量。这些发生在程序加载之前。

那么初始化的顺序就是代码段——就像构造函数一样。这些段在编译单元中从上到下出现。

在你的情况下 d=m 我想从 m 的插槽中复制值。其中设置为 0.0

然后调用 m=fun(),用正确的值复制插槽。