#[repr(C)] and #[repr(Rust)]
- Rust course
- Expert
- Lesson 8/46
- 4 min
Learn the difference between #[repr(C)] and #[repr(Rust)].
#[repr(C)] and #[repr(Rust)]
repr attributes set an explicit contract on the layout:
repr(Rust): the default; the compiler is free.repr(C): C-compatible, field order kept.repr(u8)/repr(i32): fixes an enum's discriminant type.repr(transparent): guarantees a single-field wrapper has the same ABI as the inner type.repr(packed)/repr(align(n)): remove padding or raise the alignment.
#[repr(u8)]
enum Renk { Kirmizi = 1, Yesil = 2 } // 1 byte
#[repr(transparent)]
struct Metre(f64); // same as f64Which one when?
repr(C): FFI and binary formats. repr(u8): storing an enum as a byte or matching a C enum. repr(transparent): passing a newtype in place of the inner type in FFI. repr(align(64)): preventing two threads from sharing the same cache line (false sharing). repr(packed): only for mandatory binary layouts; it has a performance and safety cost.
#[repr(align(64))]
struct Sayac(std::sync::atomic::AtomicU64); // each counter on its own cache linePractice repr attributes
Define #[repr(u8)] enum Renk { Kirmizi = 1, Yesil = 2 } and #[repr(transparent)] struct Metre(f64);. Print size_of::<Renk>(), Renk::Yesil as u8 and size_of::<Metre>() separated by spaces.
Starter code
fn main() {
// buraya yaz
}Sample solution
#![allow(dead_code)]
use std::mem::size_of;
#[repr(u8)]
enum Renk {
Kirmizi = 1,
Yesil = 2,
}
#[repr(transparent)]
struct Metre(f64);
fn main() {
println!("{} {} {}", size_of::<Renk>(), Renk::Yesil as u8, size_of::<Metre>());
}Expected output
1 2 8
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why is taking a reference to a field of a <code>repr(packed)</code> struct a problem?
- It isn't a problem
- The size changes
- The field may be unaligned; an unaligned reference is undefined behaviour Correct answer
- The fields are private
Explanation: That's why the compiler treats references to packed fields as an error; the value is read by copying, or with addr_of! and read_unaligned.
2 Transparent wrapper
#[repr(____)]
struct Metre(f64);
#[repr(transparent)]
struct Metre(f64);
Explanation: repr(transparent) makes the wrapper have the same ABI as the inner type.
3 repr and effect
| Term | Meaning |
|---|---|
repr(C) |
C-compatible layout |
repr(u8) |
1-byte discriminant |
repr(transparent) |
Same ABI as inner type |
repr(align(64)) |
64-byte alignment |