Rust ABI对枚举紧凑性有什么保证?

cut*_*lus 1 rust

据我所知,Rust ABI不稳定.但是,Rust编译器当前执行一些优化以将字段压缩到标记中.例如:

use std::mem::size_of;

enum Node {
    N1_1 {
        is_good: bool,
        stuff: u32,
    },
    N1_2 {
        is_good: bool,
        left: Box<Node>,
        right: Box<Node>,
    },
}

enum Node2 {
    N2_1 { stuff: u32 },
    N2_2,
}

fn main() {
    println!("{:?} {:?}", size_of::<Node>(), size_of::<Node2>());
}
Run Code Online (Sandbox Code Playgroud)

这打印24 8.显然,正在发生的是字段被折叠到构造函数标记中.这种行为有保证吗?我不是在询问特定的内存表示是否保持不变,而是否承诺未来某个时间点的大小不会增加.

我想不出一个很好的理由,为什么他们可能想在某些时候改变代表性以增加尺寸,但也许这只是我缺乏想象力,所以我正在寻找一个"官方"答案.

与GitHub问题/ RFC的链接会很有帮助.我尝试浏览问题跟踪器,但无法找到任何内容.我能找到的最接近的东西bool是1字节大小,这是无法保证的.

She*_*ter 6

这种行为有保证吗?

不,Rust ABI 不保证任何形式,这就是"不稳定"的含义.只要代码工作并且ABI之外的其他保证被保留,开发人员就能够在他们认为合适时更改它.

真的,在这种情况下,你不像在做类型布局那样关心ABI .参考文献说,强调我的:

没有repr属性的标称类型具有默认表示.非正式地,这种表示也称为rust表示.

此表现毫不数据布局的保证.

他们可能想要在某些时候改变表示以增加大小的一个很好的理由

一个可能的原因是因为填充或对齐等概念.有可能(但不太可能)有人发现将每个结构对齐到331个字节会使代码运行速度提高53倍.


rustc +nightly -Zprint-type-sizes enum-compactness.rs
Run Code Online (Sandbox Code Playgroud)
type: `Node`: 24 bytes, alignment: 8 bytes
    discriminant: 1 bytes
    variant `N1_1`: 7 bytes
        field `.is_good`: 1 bytes
        padding: 2 bytes
        field `.stuff`: 4 bytes, alignment: 4 bytes
    variant `N1_2`: 23 bytes
        field `.is_good`: 1 bytes
        padding: 6 bytes
        field `.left`: 8 bytes, alignment: 8 bytes
        field `.right`: 8 bytes
Run Code Online (Sandbox Code Playgroud)
type: `Node2`: 8 bytes, alignment: 4 bytes
    discriminant: 4 bytes
    variant `N2_1`: 4 bytes
        field `.stuff`: 4 bytes
    variant `N2_2`: 0 bytes
Run Code Online (Sandbox Code Playgroud)