Why is this Rust enum not smaller?

余生颓废 提交于 2019-12-10 15:57:11

问题


Consider this silly enum:

enum Number {
    Rational {
        numerator: i32,
        denominator: std::num::NonZeroU32,
    },
    FixedPoint {
        whole: i16,
        fractional: u16,
    },
}

The data in the Rational variant takes up 8 bytes, and the data in the FixedPoint variant takes up 4 bytes. The Rational variant has a field which must be nonzero, so i would hope that the enum layout rules would use that as a discriminator, with zero indicating the presence of the FixedPoint variant.

However, this:

fn main() {
    println!("Number = {}", std::mem::size_of::<Number>(),);
}

Prints:

Number = 12

So, the enum gets space for an explicit discriminator, rather than exploiting the presence of the nonzero field.

Why isn't the compiler able to make this enum smaller?


回答1:


Although simple cases like Option<&T> can be handled without reserving space for the tag, the layout calculator in rustc is still not clever enough to optimize the size of enums with multiple non-empty variants.

This is issue #46213 on GitHub.

The case you ask about is pretty clear-cut, but there are similar cases where an enum looks like it should be optimized, but in fact can't be because the optimization would preclude taking internal references; for example, see Why does Rust use two bytes to represent this enum when only one is necessary?



来源:https://stackoverflow.com/questions/57326734/why-is-this-rust-enum-not-smaller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!