CodeBlanks Logo Icon CodeBlanks

#[repr(C)]

Define C-compatible structs with #[repr(C)].

#[repr(C)]

Rust is free to change the order and padding of struct fields in memory; it usually reorders fields to save space. For structs passed to C, the layout must be the same as C's. #[repr(C)] places fields in the written order with C's rules:

#[repr(C)]
struct Paket {
    a: u8,    // 1 byte + 3 padding
    b: u32,   // 4 bytes
    c: u8,    // 1 byte + 3 padding
}           // 12 bytes total

struct Serbest { a: u8, b: u32, c: u8 }   // Rust reorders: 8 bytes

Measuring layout

size_of and align_of give the layout at compile time; std::mem::offset_of! shows a field's distance from the start:

use std::mem::{align_of, offset_of, size_of};

println!("{}", size_of::<Paket>());        // 12
println!("{}", align_of::<Paket>());       // 4
println!("{}", offset_of!(Paket, b));      // 4
println!("{}", offset_of!(Paket, c));      // 8

For enums, #[repr(u8)] or #[repr(C)] fixes the discriminant's type and layout.

Practice Layout comparison

Define a #[repr(C)] struct Paket and a plain struct Serbest with the same fields (a: u8, b: u32, c: u8). Print the size_of of both separated by a space.

Starter code

main.rs
use std::mem::size_of;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
#![allow(dead_code)]
use std::mem::size_of;

#[repr(C)]
struct Paket {
    a: u8,
    b: u32,
    c: u8,
}

struct Serbest {
    a: u8,
    b: u32,
    c: u8,
}

fn main() {
    println!("{} {}", size_of::<Paket>(), size_of::<Serbest>());
}

Expected output

12 8

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why are 3 bytes of padding added before the u32 field?

  • The u32's address must be a multiple of 4 (alignment) Correct answer
  • It's not a C rule
  • Randomly for speed
  • It isn't added

Explanation: Each type must sit at an address that's a multiple of its alignment; the struct's size is also rounded up to a multiple of the largest alignment.

2 C layout

Question
#[____]
struct Paket {
    a: u8,
    b: u32,
}
Answer
#[repr(C)]
struct Paket {
    a: u8,
    b: u32,
}

Explanation: repr(C) lays out fields with C rules, in the written order.

3 Expression and result (Paket)

Term Meaning
size_of::<Paket>() 12
align_of::<Paket>() 4
offset_of!(Paket, b) 4 (offset)
size_of::<Serbest>() 8

All lessons in Advanced