所有“真正的”C ++编译器都没有使用内置类型的零进行默认初始化吗?我问'我发现on-line compilers声称是gcc,并且内置类型的初始化为零
int h=6548;
for (int i; i < 10; ++i) {
cout<<i<<"\n";
}
对于此代码,其输出为
0
1
2
3
4
5
6
7
8
9
答案 0 :(得分:2)
什么初始化。在您的示例中,访问i
是
未定义的行为,因为它没有初始化。一些编译器
执行初始化它,至少在调试模式下,但通常是
像0xDEADBEEF
或0xCCCCCCCC
这样的东西,你可以
在调试器中轻松识别您正在访问
未初始化的内存(以便程序可能崩溃)
如果你用它作为指针),但这不是必需的。
隐式初始化内置类型的唯一时间是
它们具有静态存储持续时间:定义的变量
命名空间范围(包括静态类成员)或本地
已声明为static
的变量。
您不会显示代码的上下文,但如果是直接的话
在main
中,或在main
调用的第一个函数中,int i
将是这个实际记忆的第一次使用。和操作系统
出于安全原因,可能会将其设置为0。你可能会
想尝试类似的事情:
void scribble()
{
int x = 0x12345678;
}
void testit()
{
for ( int i; i < 10; ++ i ) {
std::cout << i << '\n';
}
}
int
main()
{
scribble();
testit();
return 0;
}
对std::operator<<( std::ostream&, char const* )
的致电是
可能在这里留下了与0不同的东西
特定的记忆细胞。 (或者编译器已经优化了它。
在关闭所有优化的情况下尝试这一点。)无论是g ++还是
VC ++初始化i
中的testit
。
答案 1 :(得分:2)
值是否初始化是未定义的行为和实现相关。你不能依赖它。
如果为对象指定了 no initializer ,则默认初始化该对象;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定值。 [注意:具有静态或线程存储持续时间的对象是零初始化的,请参见3.6.2。 - 后注]
如果您使用int i;
,则会产生未初始化的整数,其中包含“ indeterminate value ”!如果您访问它的值,则无法预测会发生什么。
一个对象,其初始化程序是一组空的括号,即(),应该是值初始化。
如果您使用int i = int();
,则您的值已初始化i
。现在,什么是价值初始化?
值初始化 T 类型的对象意味着:
- [...](T可能是类或数组类型的一些选项)
- 否则,对象零初始化。
好了,现在我们知道int i = int();
表示有i=0
。
请注意以下事项:
注意:由于初始化程序的语法不允许使用(),
X a();
不是类X的值初始化对象的声明,而是函数的声明,不带参数并返回X.
强调标准报价是我的。
答案 2 :(得分:1)
C和C ++标准都很清楚,只有一种内存可以初始化,那就是静态存储的内存。
具有静态存储持续时间的变量保证为零(未初始化或具有构造函数)。其他一切都是&#34;未初始化&#34;,这意味着&#34;你不知道它会是什么&#34; - 其中一个选项当然是零。
所有其他变量几乎都保证不会为零,至少在某些情况下 - 并且很可能您无法通过简单的测试程序找到这些情况。
例如,malloc
(或new
)内存通常为零&#34;处女&#34;记忆,但填写一些东西,然后释放它并再次使用它,它不再是零。
堆栈上的变量几乎不可避免地会有不同的值,具体取决于前一次调用的内容(因此,在代码访问的前一个函数中放入堆栈的内容)。
答案 3 :(得分:0)
它可能依赖于编译器到编译器,但最好让初始化成为一种习惯,因为你可能不知道你最终会使用哪个旧编译器,并且你可能会因使用未初始化的垃圾值而搞砸.... 另一个编译器是http://codepad.org/,它也在初始化..
答案 4 :(得分:0)
没有一个编译器初始化为零。我可以说你很幸运。 在你给的在线编译器中尝试这个。
for(int i;i < 10; ++i)
{
int a;
cout << a << endl;
a = 1;
}
你会看到第一次a等于0,接下来9次等于1。