enum Foo {
OptionA,
OptionB,
OptionC,
}
enum Bar {
OptionA = 1,
OptionB = 2,
OptionC = 4,
}I didn't know this. How is determined? Is there any code inserted by the compiler to do this?
What's the overhead of using Result<T, E>?
> What's the overhead of using Result<T, E>?
Enough bits (+ padding) to discriminate between all the variants, as any tagged union would, modulo some tricks for niche optimization. For example, Result<i64, u64> is 16 bytes in memory because it needs 8 bytes to represent either a i64 or an u64, plus another 8 bytes to determine whether it is an Ok or an Err. You can think of it as a
struct Enum {
variant: usize,
bytes: [u8; N],
}
The niche optimization I mentioned applies for things like Option<NonZeroI64>, where NonZeroI64 fits in 8 bytes but the compiler can ensure that the bitpattern corresponding to the 0 value will never be used, so it can use that to differentiate between Some and None.https://play.rust-lang.org/?version=stable&mode=debug&editio...
Regarding code: because of the "to determine at runtime" of your parent comment, I thought there could be some runtime checks (extra code) for handling enums.
I don't think I have come across any conversation by embedded developers foregoing enums because of that, but anecdotally that space does seem to rely on type state machines a bit more than others, which have no runtime memory cost. A bigger cost consideration is if you have an enum with variants that have wildly different sizes, making the enum big for all cases, whether it is necessary or not. We have a lint to encourage you to Box wildly diverging variants, but that might not be possible if you don't have an allocator.
> Regarding code: because of the "to determine at runtime" of your parent comment, I thought there could be some runtime checks (extra code) for handling enums.
Yeah, I figured that's what happened and I should be more careful with my wording.
[1]: https://doc.rust-lang.org/reference/items/unions.html