P.UNS.MEM.01 要注意选择合适的结构体、元组、枚举的数据布局

【描述】

对于 Rust 中结构体和元组,编译器会随意重排其字段来优化布局。请根据具体的场景来选择合适的数据布局。

可以通过以下 #[repr] 属性来控制结构体和元组的数据布局:

  • #[repr(Rust)] ,默认 Rust 数据布局
  • #[repr(C)] ,与 C 兼容的布局
  • #[repr(align(N))] ,指定对齐方式
  • #[repr(packed)] ,指定字段将不在内部对齐
  • #[repr(transparent)] ,让包含单个字段的结构体布局和其字段相同

可以通过以下 #[repr] 属性来控制枚举体的数据布局:

  • 特定整数类型
    • #[repr(u8)]
    • #[repr(u16)]
    • #[repr(u32)]
    • #[repr(u64)]
    • #[repr(i8)]
    • #[repr(i16)]
    • #[repr(i32)]
    • #[repr(i64)]
  • C 兼容布局
    • #[repr(C)]
  • 指定判别式大小的 C 兼容布局
    • #[repr(C, u8)]
    • #[repr(C, u16)]
    • 以此类推

枚举需要注意的地方:

  • 枚举不允许通过 #[repr(align)] 手动指定对齐方式。
  • 空枚举不能使用 repr 属性
  • 无字段枚举不允许指定判别式大小的 C 兼容布局,比如 [repr(C, Int)]
  • 数据承载(有字段)枚举则允许所有类型的 repr 属性