额外的字节是否在C++中初始化为 0?

Are extra bytes initialized to 0 in C++?

本文关键字:初始化 C++ 字节 是否      更新时间:2023-10-16

假设我有一个包含 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(