Course contentsShow
← Rust
Lesson 497 of 1,9105. Type System and TraitsFree lesson

Internal Memory Layout and Representation

Control struct layout and padding for inter-process communication using type attributes.

In this lesson, you will learn how to stabilize the memory layout of your structs using type attributes to ensure they can be safely shared across different processes or foreign languages.

The Problem with Default Layouts

By default, Rust does not guarantee a specific memory layout for your structs. To optimize performance, the compiler is free to reorder your fields to minimize the size of the struct (a process called "field reordering").

While this is excellent for internal Rust performance, it is disastrous for Inter-Process Communication (IPC). If Process A sends a raw byte buffer of a struct to Process B, but they both interpreted the order of fields differently, your data would be corrupted.

Controlling Layout with repr

To solve this, we use the #[repr(C)] attribute. This tells the compiler to use the C programming language's memory layout rules. In the C layout:

  1. Fields are kept in the exact order you define them.
  2. The compiler will insert padding bytes to satisfy alignment requirements, ensuring that fields start at predictable memory addresses.

Practical Example

If you are writing a header for a network packet that needs to be read by another program, you should define it like this:

#[repr(C)]
struct NetworkPacket {
    header_id: u32,
    payload_size: u16,
    // The compiler will add 2 bytes of padding here 
    // to align the next 32-bit integer to a 4-byte boundary.
    timestamp: u32, 
}

By applying #[repr(C)], you force the compiler to stop "optimizing" the field order. This makes the memory structure deterministic. Any process reading that memory address can reliably find header_id at the start, payload_size four bytes later, and timestamp following the padding.

It is important to remember that repr(C) is the primary tool for binary stability. If you change your struct definition, you must ensure that both the sender and receiver are updated, as the padding and layout remain sensitive to the specific types used.

Key Takeaway: Use the #[repr(C)] attribute to force a predictable, ordered memory layout, which is essential when sharing data structures between different processes or systems.