命名空间范围变量的 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 作为输出。
是的,d2
和 m
都有静态存储持续时间,因为它们是在命名空间范围内声明的,未修饰的。
这意味着它们是 零初始化 作为任何其他初始化发生之前的第一步。然后,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()
,用正确的值复制插槽。
考虑以下程序:(查看现场演示 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 作为输出。
是的,d2
和 m
都有静态存储持续时间,因为它们是在命名空间范围内声明的,未修饰的。
这意味着它们是 零初始化 作为任何其他初始化发生之前的第一步。然后,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()
,用正确的值复制插槽。