C++隐式类型何时初始化为0
When are C++ implicit types initialized to 0?
在与同事讨论后,我产生了一些疑问。。。
正如标题所问,什么时候可以假设内置类型将初始化为0而不是未知值?
c++标准之间的规则是否不同?
完整的规则在[dcl.init](C++11)中。总结一下:当声明中没有提供初始化程序时,实体就是所谓的默认初始化程序对于类类型,这意味着调用了默认构造函数。对于非类类型,这意味着不执行初始化
然而,[dcl.init]§9指出:"在任何其他初始化发生之前,静态存储持续时间的每个对象在程序启动时都是零初始化的。"
这意味着非类类型的静态持续时间变量(如命名空间范围变量)初始化为零。其他非类类型的对象(如局部变量)是而不是初始化的。
我将尝试提供一些代码,让编译器为您初始化成员:
struct POD {
int a;
double b; //...
};
// namespace level:
POD p;
void f() {
POD n1; // uninitialized
POD p1 = {};
POD p2 = POD();
POD* n2 = new POD; // uninitialized
POD* pp1 = new POD();
delete n2; delete pp1;
}
在上面的例子中,只有标有"未初始化"的才会被初始化。请注意,这与标准的要求有关,不同的编译器的里程数会有所不同。特别是VS在某些情况下与T t = T();
和T* p = new T()'
有一些问题(IIRC,当类型T
不是POD,但没有用户提供的默认构造函数时,编译器将无法初始化POD子对象:
struct T {
std::string s;
int i;
};
void f() {
T t = T(); // t.i == 0 according to the standard
}
理论:
根据C++98和C++03标准:
3.6.2非本地对象的初始化,§1:
具有静态存储持续时间(3.7.1)的对象应在进行任何其他初始化之前进行零初始化(8.5)。
3.7.1静态存储持续时间,§1:
所有既没有动态存储持续时间也不是本地的对象都有静态存储持续时间
3.7.1静态存储持续时间,§3:
关键字
static
可用于声明具有静态存储持续时间的局部变量。
以及8.5初始化程序,§6:
在进行任何其他初始化之前,静态存储持续时间的每个对象应在程序启动时进行零初始化。
这在两个标准中是相同的。唯一的区别是C++98的8.5§6:的公式
任何静态存储持续时间的对象占用的内存应为零初始化在程序启动时,在进行任何其他初始化之前。
示例:
这里是一个示例,其中x
和y
具有静态存储持续时间,因此标准保证它们在程序启动时都将为零初始化。注意,还有以相同方式声明的POD对象a
和b
,因此具有静态存储持续时间,这意味着它们的成员(i
和d
)也将被零初始化:
struct POD {
int i;
double d;
};
int x;
POD a;
int foo() {
static int y;
return y;
}
int main() {
static POD b;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << foo() << std::endl;
std::cout << "a.i = " << a.i << std::endl;
std::cout << "b.d = " << b.d << std::endl;
}
这个例子的输出当然是:
x = 0
y = 0
a.i = 0
b.d = 0
我不认为任何隐式类型都会初始化为0。当您在调试器内部运行并使用调试堆/堆栈时,您可能会发现这种情况。当您在调试器之外或通过_NO_debug_HAP=1环境变量禁用调试堆时,或者在其他情况下,您会发现在大多数情况下内存未初始化。
根据经验,初始化变量,因为这样编程更安全。
编辑:正如Luchian Grigore所指出的,全局/命名空间范围变量是一个例外。由于这种初始化,它们通常也无法处理未初始化的变量检查。
- 何时为派生类初始化 vptr?
- c++ 中的异常类何时初始化?
- 何时以及如何初始化和销毁thread_local变量?
- 在运行时,何时完全初始化 std 库才能在不破坏代码的情况下使用它?
- 静态存储中的内联变量何时初始化?
- c++:何时初始化声明的变量而不将其分配给任何值
- 何时分配和初始化变量
- 模板非静态数据成员初始化程序何时实例化
- 声明并初始化指针后,何时在变量文本前面加上星号,何时不作为前缀
- QObject 自定义属性何时从样式表中指定的值初始化
- 初始化引用时何时以及为何获得副本
- 在构造函数的初始化列表中初始化时,何时构造成员对象?
- 何时在C++中使用哪个数据成员初始化
- 何时使用外部链接初始化全局常量,避免静态初始化顺序惨败
- 静态成员何时在 C++ 中初始化
- 在静态初始化期间,pthread线程变量何时开始存在
- 何时初始化静态变量和全局变量
- 指针初始化:何时给初始化的指针赋NULL值
- 何时用256初始化数组
- 聚合的列表初始化:何时可以调用复制构造函数