额外的字节是否在C++中初始化为 0?
Are extra bytes initialized to 0 in C++?
假设我有一个包含 int 和 char 的结构:
struct thing_t {
int value = 0;
char other_value = 0;
};
由于内存中的对齐方式,sizeof(thing_t)
应为 8,因为最大成员的大小为 4 字节。如果我创建一个默认初始化的thing_t
实例,多余的 3 个字节会初始化为 0 吗?
我认识到这通常不会出现,但我正在编写一个哈希函数,哈希函数的默认行为是对泛型类型进行哈希处理,就好像它是一个字节数组一样。如果额外的字节偶尔没有初始化为 0,我意识到我的方法可能会导致问题。
我在 C++11 标准中找不到任何关于默认初始化对象时填充会发生什么的信息。
但是,当涉及到零初始化时,标准对填充是坚定的。
从 8.5 初始值设定项/5
5.2 — 如果 T 是(可能符合 cv 条件的(非联合类类型,则每个非静态数据成员和每个基类子对象初始化为零,填充初始化为零位;
5.3 — 如果 T 是(可能符合 cv 条件的(联合类型,则对象的第一个非静态命名数据成员初始化为零,填充初始化为零位;
我建议使用零初始化而不是默认初始化来强制将填充位初始化为零。这将导致哈希函数产生可预测的值。
如果我创建一个默认初始化的 thing_t 实例,多余的 3 个字节会初始化为 0 吗?
他们可能是也可能不是。 没有要求将它们归零。
遗憾的是,您无法对对象进行值初始化以使其初始化为零,这会将填充位归零,因为默认成员发起器会阻止它轻松构造。
[dcl.init]/8
对 T 类型的对象进行值初始化意味着:
[...]
- 如果 T 是没有用户提供或删除的默认构造函数的(可能符合 cv 条件的(类类型,则对象为零初始化并检查默认初始化的语义约束,如果 T 具有非平凡的默认构造函数,则对象为默认初始化;
[类]/6
如果默认构造函数不是用户提供的,并且
如果:[...]
- 其类的任何非静态数据成员都没有默认成员初始值设定项 (12.2(
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员