簡體   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