【发布时间】:2018-07-26 08:47:47
【问题描述】:
根据http://en.cppreference.com/w/cpp/language/zero_initialization,我无法理解我班级中的某个成员何时以及为何被零初始化。
考虑以下测试程序:
#include <iostream>
#include <stdio.h>
class MyTest {
private:
const static unsigned int dimension = 8;
void (* myFunctions [dimension])();
public:
MyTest() {}
void print() {
for(unsigned int i=0; i < MyTest::dimension; i++) {
printf("myFunctions[%d] = %p\n", i, this->myFunctions[i]);
}
}
};
int main() {
//We declare and initialize an object on the stack
MyTest testObj = {};
testObj.print();
return 0;
}
我声明一个类有一个由签名“void functionname()”的 8 个函数指针组成的数组。当我将main 中的类对象声明并初始化为MyTest testObj = {}; 或MyTest testObj; 时,我希望它是零初始化的,即所有指针都是空指针。
但是,在我的带有g++ -m32 -o test -std=c++14 test.cpp && test 机器的 Windows 10 机器上使用 g++ 5.3.0 编译会得到输出:
myFunctions[0] = 76dd6b7d
myFunctions[1] = 00401950
myFunctions[2] = 0061ff94
myFunctions[3] = 004019ab
myFunctions[4] = 00401950
myFunctions[5] = 00000000
myFunctions[6] = 003cf000
myFunctions[7] = 00400080
看起来像堆栈中未初始化的值..
如果我将对象的声明移到 main 之外(作为全局变量),它会再次打印全零。
如果我正确理解了 cppreference,这是因为我有一个静态存储持续时间的变量,因此是零初始化的。它通过对我的类的所有非静态数据成员(即myFunctions)数组进行零初始化来初始化我的类类型。一个数组是通过对它的每个元素进行零初始化来初始化的,在我的函数指针的情况下,它是一个空指针。
为什么当我使用MyTest testObj = {}; 声明我的对象堆栈时,它没有对堆栈进行零初始化?
【问题讨论】:
-
我不符合你的期望。显然,您链接的文档页面中的三点都不适用。
-
MyTest testObj = {}不是零初始化。它是值初始化,它只是调用默认构造函数,在您的情况下它什么都不初始化。 -
MyTest() {}构造函数没有初始化任何东西。 -
这种行为是否特定于函数指针?
-
注意:
6.6.2 Static initialization静态存储持续时间的对象初始化为零。这就是为什么当你把它设为全局变量时,一切都被初始化为零。自动对象遵循稍微复杂的规则。
标签: c++ c++14 zero-initialization