repr 属性的对齐方式
现代计算机硬件中的 CPU 在数据自然对齐时,可以最有效地执行对存储器的读写,这通常意味着数据地址是数据大小的倍数。 数据对齐是指根据元素的自然对齐来对齐元素。为了确保自然对齐,可能需要在结构元素之间或结构的最后一个元素之后插入一些填充值。
#[repr]
属性有一个新参数 align
,用于设置结构体的对齐方式:
#![allow(unused_variables)] fn main() { struct Number(i32); assert_eq!(std::mem::align_of::<Number>(), 4); assert_eq!(std::mem::size_of::<Number>(), 4); #[repr(align(16))] struct Align16(i32); assert_eq!(std::mem::align_of::<Align16>(), 16); assert_eq!(std::mem::size_of::<Align16>(), 16); }
如果您正在使用底层级别的东西,控制这些事情可能非常重要!
一般来说,类型的对齐并不担心,因为编译器将为一般用例选择适当的对齐“做正确的事情”。 但是,在使用外部系统操作时,可能需要非标准对齐。例如,通过自定义对齐,这些情况往往需要或更容易:
- 当硬件实际上仅由4字节值组成时,硬件通常具有模糊的要求,例如“此结构对齐到32字节”。虽然这通常可以手动计算和管理,但将它表达为类型的属性通常也很有用,可以让编译器做一些额外的工作。
- 像
gcc
和clang
这样的C编译器提供了为结构指定自定义对齐的能力,如果 Rust 也可以镜像自定义对齐的请求(例如将结构传递给C),Rust 可以更容易地与这些类型进行互操作。正确的更容易)。 - 自定义对齐通常可以在这里和那里用于各种技巧,并且通常很方便,因为“让我们使用实现”工具。例如,这可用于在内核中静态分配页表,或者为并发编程轻松创建至少缓存行大小的结构。
此功能的目的是提供轻量级注释,以更改结构的编译器推断对齐,从而更轻松地启用这些情况。