问题标签 [zero-initialization]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
135 浏览

c++ - 在 C++ 中初始化数组:最快的方法?

在 C++ 中用零初始化 int 数组的最快方法是什么?

或者

或者也许还有另一种方式?

0 投票
5 回答
5614 浏览

c++ - 为什么定义数组之外的第一个元素默认为零?

我正在为我的 C++ 课程简介准备期末考试。我们的教授给我们练习了这个问题:

解释为什么代码会产生以下输出:120 200 16 0

该问题的示例答案是:

cout 语句只是循环遍历数组元素,其下标由 for 循环的增量定义。元素大小不是由数组初始化定义的。for 循环定义了数组的大小,恰好超过了初始化元素的数量,因此对于最后一个元素默认为零。第一个 for 循环打印元素 0 (120),第二个打印元素 1 (200),第三个循环打印元素 2 (16),第四个循环打印默认数组值 0,因为没有为元素 3 初始化任何内容。此时点 i 现在超过了条件并且 for 循环终止。

我有点困惑,为什么数组外的最后一个元素总是“默认”为零。只是为了实验,我将问题中的代码粘贴到我的 IDE 中,但将 for 循环更改为for (int i = 0; i < 8; i++). 然后输出变为120 200 16 0 4196320 0 547306487 32655。为什么尝试访问超出定义大小的数组中的元素时没有错误?程序是否只输出上次将值保存到该内存地址时存在的任何“剩余”数据?

0 投票
2 回答
135 浏览

arrays - C自动将空字符附加到字符串?

这是我的一项测试,我不明白为什么它会按预期工作。这是一段代码,将s1的顺序颠倒过来,存储在s2中,然后打印出来。在我看来,当 s1 向后存储时,s2 中的空字符将被覆盖,而且 s1 中的空字符永远不会被写入 s2,因为它是从最后一个字符开始的。但它打印出来就好了。为什么?

0 投票
1 回答
47 浏览

c++ - 如何初始化多维 C++ 标准数组,包括零初始化?

我有一个二维 std 数组,例如 array<array<int, 9>, 9> tbl;

如何用-1等相同的值初始化它?如果我只是希望它被零初始化,那么最好的方法是什么?

0 投票
1 回答
577 浏览

c++ - C++ 标准是否保证非静态聚合对象的填充字节初始化为零?

C++ 是否支持允许我们将对象及其所有填充字段初始化为零的语言结构。我在 cppreference.com 中找到了一些关于零初始化的令人鼓舞的措辞,这表明在某些情况下,填充字节也将被归零。

引用 cppreference.com: 零初始化

在以下情况下执行零初始化:

  1. 作为非类类型和没有构造函数的值初始化类类型成员的值初始化序列的一部分,包括未提供初始化器的聚合元素的值初始化。

零初始化的效果是:

  • 如果 T 是标量类型,则对象的初始值是显式转换为 T 的整数常量零。
  • 如果 T 是非联合类类型,则所有基类和非静态数据成员都初始化为零,并且所有填充都初始化为零位。构造函数(如果有)将被忽略。
  • ...

人们会在value-initializationaggregate-initializationlist-initialization中找到对零初始化的引用。

我使用相当最新的 GCC 和 clang C++ 编译器进行了测试,它们的行为似乎不同。

坦率地说,我努力解析这些规则,特别是考虑到不同的编译器行为,我无法弄清楚如何正确解释这些规则。

请参阅此处的代码(需要最低 C++11)。结果如下:

给定:Foo

构造 克++ 铿锵++
富() x:[----][0x42][0x43][0x44],v: 0 x:[----][----][----][----],v: 0
y:[----][----][----][----],v: 0 y:[----][----][----][----],v: 0
z:[----][0x4A][0x4B][0x4C],v: 0 z:[----][----][----][----],v: 0
富{} x:[----][----][----][----],v: 0 x:[----][0x42][0x43][0x44],v: 0
y:[----][----][----][----],v: 0 y:[----][----][----][----],v: 0
z:[----][----][----][----],v: 0 z:[----][0x4A][0x4B][0x4C],v: 0

这里[----]表示一个包含所有位 0 的字节,并且[0x..]是垃圾值。

如您所见,编译器输出表明填充未初始化。Foo()和都是Foo{}值初始化。此外还有Foo{}一个聚合初始化,缺少初始化程序。为什么没有触发零初始化规则?为什么没有触发填充规则?

我已经明白依赖填充字节为零不是一个好主意,甚至可能是未定义的行为,但我认为这不是这个问题的重点。

  • 问题 1:标准是否提供了一种可靠地初始化填充字节的方法?
  • 问题 2:另请参阅:c 是否初始化结构填充。是否适用?
  • 问题 3:这些编译器是否符合标准?
  • 问题 4:编译器明显不同的行为的解释是什么?