繁体   English   中英

Rust 中的结构体填充规则

[英]Struct padding rules in Rust

Recently when I was learning Type Layout in Rust ( https://doc.rust-lang.org/reference/type-layout.html ), I saw that struct in Rust supports the #[repr(C)] directive, so I想看看默认(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());
}

我得到以下 output: 在此处输入图像描述 我了解填充 #[repr(C)] 结构的规则和整个结构的大小,但让我感到困惑的是 Rust 表示结构 ACG1,我找不到关于 Rust 填充规则的任何明确文档,以及我觉得padding的大小也应该包含在结构体的整体大小中,但是为什么ACG1的大小只有12字节呢?

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

这个板条箱似乎没有考虑字段重新排序。 看来编译器将结构重新排序为先具有upper

struct ACG1 {
    upper: u32,
    time1: u16,
    time2: u16,
    lower: u16,
}

它有点难看,但派生宏实现检查声明 order 中字段之间的差异。 所以从这个意义上说,结构的开头和第一个字段( time1 )之间4 个字节的“填充”,第三个字段( upper )和第四个字段( lower )之间有 4 个字节的“填充”。 存在一个问题,它不适用于非#[repr(C)]结构,因此我不建议为此目的使用此板条箱。

至于 Rust 的规则 go,参考资料说“没有保证 [默认] 表示形式的数据布局。” 所以理论上,编译器可以做任何事情,并根据访问模式对字段重新排序。 但在实践中,我认为按字段大小进行精心组织和组织并不是最小化填充的简单方法。

正如其他人所说,这似乎是板条箱中的一个问题。 最好问编译器:

cargo clean
cargo rustc -- -Zprint-type-sizes

这会给你:

...
print-type-size type: `ACG1`: 12 bytes, alignment: 4 bytes
print-type-size     field `.upper`: 4 bytes
print-type-size     field `.time1`: 2 bytes
print-type-size     field `.time2`: 2 bytes
print-type-size     field `.lower`: 2 bytes
print-type-size     end padding: 2 bytes
print-type-size type: `ACG2`: 12 bytes, alignment: 4 bytes
print-type-size     field `.time1`: 2 bytes
print-type-size     field `.time2`: 2 bytes
print-type-size     field `.upper`: 4 bytes
print-type-size     field `.lower`: 2 bytes
print-type-size     end padding: 2 bytes

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM