Why does Rust use two bytes to represent this enum when only one is necessary?

强颜欢笑 提交于 2019-12-10 17:35:51

问题


It appears to be smart enough to only use one byte for A, but not smart enough to use one byte for B, even though there are only 8*8=64 possibilities. Is there any way to coax Rust to figure this out or do I have to manually implement a more compact layout?

Playground link.

#![allow(dead_code)]

enum A {
    L,
    UL,
    U,
    UR,
    R,
    DR,
    D,
    DL,
}

enum B {
    C(A, A),
}

fn main() {
    println!("{:?}", std::mem::size_of::<A>()); // prints 1
    println!("{:?}", std::mem::size_of::<B>()); // prints 2
}

回答1:


Both bytes are necessary to preserve the ability to borrow struct members.

A type in Rust is not an ideal set of values: it has a data layout, which describe how the values are stored. One of the "rules" governing the language is that putting a type inside a struct or enum doesn't change its data layout: it has the same layout inside another type as it does standalone, which allows you to take references to struct members and use them interchangeably with any other reference.*

There's no way to fit two As into one byte while satisfying this constraint, because the size of A is one whole byte -- you can't address a part of a byte, even with repr(packed). The unused bits just remain unused (unless they can be repurposed to store the enum tag by niche-filling).

*Well, repr(packed) can actually make this untrue. Taking a reference to a packed field can cause undefined behavior, even in safe code!



来源:https://stackoverflow.com/questions/54499156/why-does-rust-use-two-bytes-to-represent-this-enum-when-only-one-is-necessary

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