#[repr(C)]
- Rust course
- Advanced
- Lesson 37/81
- 4 min
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 bytesMeasuring 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)); // 8For 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
use std::mem::size_of;
fn main() {
// buraya yaz
}Sample solution
#![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
#[____]
struct Paket {
a: u8,
b: u32,
}
#[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 |