【发布时间】:2019-12-30 09:12:14
【问题描述】:
struct Data
{
std::uint32_t b;
char a;
};
Data 类型按 4 个字节对齐,所以 sizeof(Data) == 8。
但是第 5-7 个字节中的值是什么?是默认零吗?
【问题讨论】:
-
不确定。可以是任何看似随机或“垃圾”的值。
标签: c++ c memory-alignment memory-layout
struct Data
{
std::uint32_t b;
char a;
};
Data 类型按 4 个字节对齐,所以 sizeof(Data) == 8。
但是第 5-7 个字节中的值是什么?是默认零吗?
【问题讨论】:
标签: c++ c memory-alignment memory-layout
它实际上取决于一些东西,所有细节都在 C++ 标准[dcl.init] 中。
根据存储持续时间、各种类型的构造函数的存在等,最终的各个部分要么是默认初始化、零初始化还是值初始化。
默认初始化意味着整个变量将是某个任意值,而零初始化零初始化所有成员并将填充字节设置为零。
所以Data d1; 和static Data d2; 不一定有相同的填充字节。
值初始化稍微复杂一些,因为它在调用构造函数(如果存在的话)之前有效地首先选择默认或零初始化。
但最重要的是,这可能无关紧要。如果填充的内容很重要,您应该将该空间“注册”为真正的成员变量,以便您可以使用它们(并正确初始化它们)。填充在变量的“值”中非常不重要,除非你做一些疯狂的事情,比如memcmp 它,或者在它占用的整个内存块上运行校验和:-)
【讨论】:
memset(或类似的)“清除”,因此它也可能为零。但这是一个不能指望的实现细节。只是不要假设填充空间中除了随机垃圾之外还有其他任何东西,你会没事的。
0,但不是具有静态存储持续时间的结构的填充?
#pragma pack(1) 来解决这个问题。
我一直认为这是不可预测的,但仍然不确定结构的对象是否具有静态存储持续时间。
所以我进行了搜索,看看在 C 标准和 C++ 标准中是否明确提到了这一点(因为您在 C 和 C++ 中询问)。
它被在 C 标准(C99、C11 和 C18)中提及:
J.1 未指定的行为
- 在结构或联合 (6.2.6.1) 中存储值时填充字节的值。
对于 C++,我在 C++ 标准中的任何地方都找不到它。
【讨论】:
[dcl.init] 中,涵盖了变量初始化的各种场景。看我的回答。