9.11 Memory Layout and Performance

For C programmers, understanding struct memory layout is important.

  • Field Reordering: By default, Rust does not guarantee the order of fields in memory. The compiler is free to reorder fields to optimize for padding or alignment, potentially making the struct smaller or field access faster. This differs from C where field order is guaranteed.
  • #[repr(C)]: To guarantee C-compatible field ordering and padding/alignment behavior, you can apply the #[repr(C)] attribute to the struct definition:
    #![allow(unused)]
    fn main() {
    #[repr(C)]
    struct CCompatiblePoint {
        x: f64,
        y: f64,
    }
    }
    This is essential when interoperating with C code (FFI) or requiring a specific layout for reasons like serialization or memory mapping.
  • Alignment and Padding: Rust follows platform-specific alignment rules, similar to C compilers. Padding bytes may be inserted between fields or at the end of the struct to ensure fields are properly aligned, which can impact the total size of the struct.
  • Access Performance: Accessing a struct field using dot notation (instance.field) typically requires adding a constant offset (determined at compile time) to the memory address of the struct instance, just like in C, making it very fast.

Unless C interoperability or a specific layout is required, it’s usually best to let the Rust compiler optimize the layout by omitting #[repr(C)].