基本上是这样的:
因此:您不能相信填充字节具有任何给定值(除非它们不能是陷阱表示)。填充字节的值可能因情况而异 - 不能保证它们的值是一致的。
考虑一个没有陷阱表示的普通 32 位二进制补码系统:
typedef struct
{
uint8_t u8;
uint32_t u32;
} something_t;
something_t thing1 = {1, 2};
something_t thing2 = {3, 4}
这里,一种可能的内存布局是这样的(十六进制,小端):
01 AA BB CC 02 00 00 00 // thing 1
03 55 66 77 04 00 00 00 // thing 2
^ ^ ^
u8 padding u32
在 thing1 中,01 是 u8 成员,AA BB CC 序列是用未指定值填充字节,02 00 00 00 是 u32 成员。
如果我们现在写thing1 = thing2,则允许编译器执行以下操作之一:
- 复制整个
thing2 并覆盖所有thing1,包括填充,如果这是最有效的,
-
或如果效率更高,复制
u8 和u32,但不要写入填充字节,让它们保持原样,导致thing1 现在具有内存布局03 AA BB CC 04 00 00 00。李>
这实际上就是为什么我们不能将结构与== 运算符或memcmp() 之类的函数进行比较的原因。