How is an Option laid out in memory? Since a i32 already takes up an even number of bytes, it Rust forced to use a full byte to store the single bit None/Some?
EDIT: According to this answer, Rust in fact uses an extra 4 (!) bytes. Why?
How is an Option laid out in memory? Since a i32 already takes up an even number of bytes, it Rust forced to use a full byte to store the single bit None/Some?
EDIT: According to this answer, Rust in fact uses an extra 4 (!) bytes. Why?
For structs and enums declared without special layout modifiers, the Rust docs state
Nominal types without a
repr
attribute have the default representation. Informally, this representation is also called therust
representation.There are no guarantees of data layout made by this representation.
Option
cannot possibly be repr(transparent)
or repr(i*)
since it is neither a newtype struct nor a fieldless enum, and we can check the source code and see that it's not declared repr(C)
. So no guarantees are made about the layout.
If it were declared repr(C)
, then we'd get the C representation, which is what you're envisioning. We need one integer to indicate whether it's None
or Some
(which size of integer is implementation-defined) and then we need enough space to store the actual i32
.
In reality, since Rust is given a lot of leeway here, it can do clever things. If you have a variable which is only ever Some
, it needn't store the tag bit (and, again, no guarantees are made about layout, so it's free to make this change internally). If you have an i32
that starts at 0 and goes up to 10, it's provably never negative, so Rust might choose to use, say, -1
to indicate None
.