(Sorry, if the title is kinda confusing.)
#![allow(unused)]
struct Normal {
a: u32,
b: u16,
}
struct Padded {
a: u32,
b: u16,
_padding: bool,
}
fn main() {
assert_eq!(std::mem::size_of::<Normal>(), 8);
assert_eq!(std::mem::size_of::<Option<Normal>>(), 12);
assert_eq!(std::mem::size_of::<Padded>(), 8);
assert_eq!(std::mem::size_of::<Option<Padded>>(), 8);
}
Rust somehow prefers to add 6 more bytes to Normal
when wrapping it in an Option
rather than just adding 2 bytes to yield an 8 byte alignment.
If I artificially add a padding bool
, Option
just adds a single byte, preserving the 8 byte alignment.
Using a NonZero…
also makes Option
less greedy (→ 8 bytes).
struct NonZero {
a: std::num::NonZeroU32,
b: u16,
}
Is this behavior expected? Is there a way to make an Option
of an ordinary (non-padded, non-NonZero) 6-byte type without bloating it beyond 8 bytes?
Edit: It feels like Null-Pointer-Optimization only looks for space within existing fields and otherwise falls back to just add 4 bytes to the type (with a padding of 4 bytes).