简体   繁体   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 wanna to see the difference between the default(Rust) representation and C-like representation. 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 表示之间的区别。 Here comes the code:代码如下:

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

and I get the following output:我得到以下 output: 在此处输入图像描述 I understand the rules for padding the #[repr(C)]structure and the size of the structure as a whole, but what confused me is the Rust representation struct ACG1, I can't find any clear documentation on Rust padding rules, and I think the padding size should also be included in the overall size of the structure, but why is the size of ACG1 only 12 bytes?我了解填充 #[repr(C)] 结构的规则和整个结构的大小,但让我感到困惑的是 Rust 表示结构 ACG1,我找不到关于 Rust 填充规则的任何明确文档,以及我觉得padding的大小也应该包含在结构体的整体大小中,但是为什么ACG1的大小只有12字节呢?

BTW, This is the crate I used to assist in printing the layout of the structure: https://crates.io/crates/type-layout顺便说一句,这是我用来协助打印结构布局的板条箱: https://crates.io/crates/type-layout

This crate does not seem to account for field reordering.这个板条箱似乎没有考虑字段重新排序。 It appears the compiler reordered the struct to have upper first:看来编译器将结构重新排序为先具有upper

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

Its somewhat hard to see, but the derive macro implementation checks the difference between fields in declared order .它有点难看,但派生宏实现检查声明 order 中字段之间的差异。 So in this sense, there are 4 bytes of "padding" between the beginning of the struct and the first field ( time1 ) and 4 bytes of "padding" between the third field ( upper ) and fourth field ( lower ).所以从这个意义上说,结构的开头和第一个字段( time1 )之间4 个字节的“填充”,第三个字段( upper )和第四个字段( lower )之间有 4 个字节的“填充”。 There is an issue filed that it doesn't work for non- #[repr(C)] structs, so I would not recommend using this crate for this purpose.存在一个问题,它不适用于非#[repr(C)]结构,因此我不建议为此目的使用此板条箱。

As far as Rust's rules go, the reference says "There are no guarantees of data layout made by [the default] representation."至于 Rust 的规则 go,参考资料说“没有保证 [默认] 表示形式的数据布局。” So in theory, the compiler can do whatever it wants and reorder fields based on access patterns.所以理论上,编译器可以做任何事情,并根据访问模式对字段重新排序。 But in practice, I don't think its that elaborate and organizing by field size is a simple way to minimize padding.但在实践中,我认为按字段大小进行精心组织和组织并不是最小化填充的简单方法。

As others have said, it seem to be an issue in the crate.正如其他人所说,这似乎是板条箱中的一个问题。 Better ask the compiler:最好问编译器:

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

This will give you:这会给你:

...
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