填充到底是怎么产生的?编译器自己怎么描述它?不对齐的访问有多慢?这篇让 rustc 自己把布局打印出来,逐字段看到偏移与填充,再验证对齐访问的实际表现。
编译:成功
运行(退出码 0):
u8 size 1 align 1
u16 size 2 align 2
u32 size 4 align 4
u64 size 8 align 8
u128 size 16 align 16
f64 size 8 align 8
char size 4 align 4
bool size 1 align 1
usize size 8 align 8
&u8 size 8 align 8
(u8, u32) size 8 align 4
[u16; 3] size 6 align 2
S1 size 2 align 1
S2 size 8 align 4
S3 size 16 align 8
S4 size 8 align 2repr(C) 的基础见#[repr(C)] 与内存布局。
type: `MixedC`: 32 bytes, alignment: 8 bytes
field `.a`: 1 bytes
padding: 7 bytes
field `.b`: 8 bytes, alignment: 8 bytes
field `.c`: 1 bytes
padding: 3 bytes
field `.d`: 4 bytes, alignment: 4 bytes
field `.e`: 2 bytes
end padding: 6 bytes
type: `Mixed`: 16 bytes, alignment: 8 bytes
field `.b`: 8 bytes
field `.d`: 4 bytes
field `.e`: 2 bytes
field `.a`: 1 bytes
field `.c`: 1 bytes-Z print-type-sizes 需要 RUSTC_BOOTSTRAP=1,输出格式随编译器版本变化。
编译:成功
运行(退出码 0):
size_of::<S>() = 8,元素间距 = 8 和 8
每个元素地址 % align(4) = 0 0 0
一个 u8 数组里偏移 0..8 的位置,按 u32 对齐的占 2 个,不对齐的占 6 个 编译:成功
运行(退出码 0):
对齐的 u32 读取(偏移 0): 每次 0.45 ns
不对齐的 u32 读取(偏移 1): 每次 0.46 ns(read_unaligned,结果不同是因为读的字节不同:106686713290400000 对 106113205749200000)
编译:成功
运行(退出码 -6):
read_unaligned 读偏移 1 的 u32 = 0x5040302
thread 'main' (7305060) panicked at <实验目录>/src/u113e.rs:6:22:
misaligned pointer dereference: address must be a multiple of 0x4 but is 0x16b41a7e5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.耗时为本机 release 微基准;x86 与 aarch64 上不对齐访问的代价不同,只验证了本机。