Attributes and Conditional Compilation

#[repr(...)]

#[repr(...)] is the family of representation attributes that control the memory layout, field ordering, alignment, padding, and discriminant encoding of structs, enums, and unions.

Complete Reference of #[repr(...)] Attributes

Attribute Applicable To Effect on Memory Layout and ABI
(default — repr(Rust)) struct, enum, union Compiler reorders fields to minimize padding and exploits niche bit patterns
#[repr(C)] struct, enum, union Preserves source declaration field order and C ABI alignment/size rules
#[repr(transparent)] struct, single-variant enum Identical layout, niches, and register-passing ABI as the single non-ZST field
#[repr(u8)] .. #[repr(u128)], #[repr(usize)] enum Sets the enum discriminant to the specified unsigned integer type
#[repr(i8)] .. #[repr(i128)], #[repr(isize)] enum Sets the enum discriminant to the specified signed integer type
#[repr(align(N))] struct, enum, union Raises minimum alignment to power-of-two N ($1 \le N \le 2^{29}$)
#[repr(packed)] / #[repr(packed(N))] struct, union Lowers maximum field alignment to 1 (or N), eliminating padding

Valid Combinations of #[repr(...)] Modifiers

Multiple representation hints can be combined inside a single attribute (#[repr(C, align(16))]) or across stacked attributes, subject to compatibility rules:

Valid Combinations:
  #[repr(C, align(64))]   ---> C field order + minimum 64-byte alignment
  #[repr(C, packed)]      ---> C field order + 1-byte packed alignment (0 padding)
  #[repr(C, u8)]          ---> Data-carrying enum with C union layout + 1-byte `u8` tag

Invalid Combinations (Compile Errors):
  #[repr(packed, align(8))]          ---> E0587: type has conflicting packed and align hints
  #[repr(transparent, C)]            ---> E0692: transparent type cannot have other repr hints
use std::mem::offset_of;

#[repr(C, align(16))]
struct AlignedDescriptor {
    flags: u8,
    addr: u64,
}

#[repr(C, packed(2))]
struct PackedPair {
    tag: u8,
    value: u32,
}

#[repr(u16)]
#[derive(Debug, Clone, Copy)]
enum ProtocolCode {
    Handshake = 0x0001,
    KeepAlive = 0x0002,
    Disconnect = 0xFFFF,
}

fn main() {
    println!(
        "AlignedDescriptor: size = {} B, align = {} B, addr offset = {}",
        size_of::<AlignedDescriptor>(),
        align_of::<AlignedDescriptor>(),
        offset_of!(AlignedDescriptor, addr)
    );
    println!(
        "PackedPair:        size = {} B, align = {} B, value offset = {}",
        size_of::<PackedPair>(),
        align_of::<PackedPair>(),
        offset_of!(PackedPair, value)
    );
    println!(
        "ProtocolCode:      size = {} B, Disconnect = {:#06x}",
        size_of::<ProtocolCode>(),
        ProtocolCode::Disconnect as u16
    );
}
AlignedDescriptor: size = 16 B, align = 16 B, addr offset = 8
PackedPair:        size = 6 B, align = 2 B, value offset = 2
ProtocolCode:      size = 2 B, Disconnect = 0xffff

Conflicting packed and align Error (E0587)

Attempting to apply both packed and align(N) to the same type—or placing a #[repr(align(N))] struct inside a #[repr(packed)] struct—is rejected at compile time with E0587 because lowering alignment and raising alignment contradict one another.