Rust ABI使枚举紧凑性有哪些保证?

时间:2018-07-14 15:04:04

标签: rust

我知道Rust ABI不稳定。但是,Rust编译器当前执行一些优化以将字段压缩为标签。 For example

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>());
}

这将打印24 8。显然,正在发生的事情是这些字段被折叠到了构造函数标签中。这种行为得到保证吗?我不是在问特定的内存表示形式是否会保持不变,而是可以保证将来某个时间点的大小不会增加。

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

链接到GitHub问题/ RFC将很有帮助。我尝试浏览问题跟踪器,但找不到任何东西。我能找到的最接近的东西与bool大小为1字节有关,这不能保证。

1 个答案:

答案 0 :(得分:6)

  

这种行为能得到保证吗?

不。 Rust ABI不会提供任何形式的保证,这就是“不稳定”的意思。只要代码能够正常工作,并且ABI以外的其他保证得到保留,开发人员就可以根据自己的意愿对其进行更改。

确实,在这种情况下,您不必像type layout那样在意ABI。参考文献说,重点是我的:

  

没有repr属性的标称类型具有默认表示形式。非正式地,此表示形式也称为rust表示形式。

     

不能保证此表示形式的数据布局

  

他们可能要在某些时候更改表示形式以增加尺寸的充分理由

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


rustc +nightly -Zprint-type-sizes enum-compactness.rs
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
type: `Node2`: 8 bytes, alignment: 4 bytes
    discriminant: 4 bytes
    variant `N2_1`: 4 bytes
        field `.stuff`: 4 bytes
    variant `N2_2`: 0 bytes