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. 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: 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?
BTW, This is the crate I used to assist in printing the layout of the structure: 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:
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 . 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
). 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.
As far as Rust's rules go, the reference says "There are no guarantees of data layout made by [the default] representation." 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.