Rust 中的结构填充规则

hxb*_*996 6 struct padding rust

最近,当我学习Rust 中的类型布局时,我看到 Rust 中的 struct 支持 #[repr(C)] 指令,所以我想看看默认(Rust)表示和类 C 表示之间的区别。代码如下:

use type_layout::TypeLayout;

#[derive(TypeLayout)]
struct ACG1 {
    time1: u16, // 2
    time2: u16, // 2
    upper: u32, // 4
    lower: u16, // 2
}

#[derive(TypeLayout)]
#[repr(C)]
struct ACG2 {
    time1: u16, // 2
    time2: u16, // 2
    upper: u32, // 4
    lower: u16, // 2
}

fn main() {
    println!("ACG1: {}", ACG1::type_layout());
    println!("ACG2: {}", ACG2::type_layout());
}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

在此输入图像描述

我了解填充 #[repr(C)] 结构的规则以及整个结构的大小,但令我困惑的是 Rust 表示结构 ACG1。我找不到任何关于 Rust 填充规则的明确文档,并且我认为填充大小也应该包含在结构的整体大小中,但为什么 ACG1 的大小只有 12 个字节?

顺便说一句,这是我用来协助打印结构布局的板条箱:type-layout 0.2.0

kmd*_*eko 5

这个箱子似乎没有考虑到字段重新排序。编译器似乎将结构重新排序为upper第一个:

\n
struct ACG1 {\n    upper: u32,\n    time1: u16,\n    time2: u16,\n    lower: u16,\n}\n
Run Code Online (Sandbox Code Playgroud)\n

它\xe2\x80\x99s有点难以看出,但派生宏实现会检查声明 order 中字段之间的差异。因此从这个意义上说,结构体开头和第一个字段 ( ) 之间有四个字节的“填充” time1第三个字段 ( upper) 和第四个字段 ( lower) 之间有四个字节的“填充”。

\n

一个问题表明它不适用于非#[repr(C)]结构体,因此我不建议将此板条箱用于此目的。

\n

就 Rust 的规则而言,参考文献说“[默认]表示无法保证数据布局。” 因此从理论上讲,编译器可以做任何它想做的事,并根据访问模式对字段重新排序。但在实践中,我不认为按字段大小进行详细说明和组织是最小化填充的简单方法。

\n