On 64-bit architecture I would expect both to be 16 bytes since they both leave a niche for the Option bit, but Option<(u64, u32)>
counter-intuitively turns out to be larger at 24 bytes wide, why is this?
Is it a good idea to add a dummy NonZeroU32
field to make the Option
smaller or is there some downside to this (assuming again a 64-bit architecture)?
Padding is allowed to have any value, so there is no niche in (u64, u32)
.
And the size of (u64, 32)
must be 16 rather than 12 because the alignment is 8 and the size must be a multiple of the alignment.
thank you, I see.
Yes, the reasons for 16 bytes were clear to me, I just though that padding could be used for the niche.
For those looking for a longer discussion:
I wouldn't add a NonZeroU32
to the tuple because it would be confusing. If the size is important, then I would rather create a struct with the three fields and clearly document what the purpose of the NonZeroU32
is using field names and documentation.
I might use this type instead of NonZeroU32
:
/// A type that can be used in place of padding
/// in a struct or tuple to give the padding a niche
/// for the Option optimization.
#[repr(u32)]
enum PaddingWithNiche {
Padding = 1
}
Many thanks!
Actually my use-case was indeed for a struct with private fields, I just mentioned tuples for conciseness of the question.
do you happen to have a source for that? i'd like to dig into the specifics of rust layout guarantees, but i'm not able to find the relevant section of the rust reference.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.