TL;DR: I thought that the packed attribute in Rust always strips any padding between the fields but apparently this is only true for packed(1)
.
I want my struct to represent the exact bytes in memory without any additional padding between fields but the struct also needs to be page-aligned. The compiler output isn't what I expect it to be in my code example. From the language reference [ 0 ] I found, that packed(N)
aligns the struct to a N-byte boundary. I expected that only the beginning of the struct is aligned while there is never padding between the fields. However, I found out that:
#[repr(C, packed(4096)]
struct Foo {
first: u8,
second: u32,
}
let foo = Foo { first: 0, second: 0 };
println!("foo is page-aligned: {}", &foo as *const _ as usize & 0xfff == 0);
println!("{:?}", &foo.first as *const _);
println!("{:?}", &foo.second as *const _);
println!("padding between fields: {}", &foo.second as *const _ as usize - &foo.first as *const _ as usize);
results in
foo is page-aligned: false
0x7ffc85be5eb8
0x7ffc85be5ebc
padding between fields: 4
Why is the struct not page-aligned and why is there padding between the fields? I found out that I can achieve what I want with
#[repr(align(4096))]
struct PageAligned<T>(T);
#[repr(C, packed)]
struct Foo {
first: u8,
second: u32,
}
let foo = Foo { first: 0, second: 0 };
let aligned_foo = PageAligned(Foo { first: 0, second: 0 });
it results in
foo is page-aligned: true
0x7ffd18c12000
0x7ffd18c12001
padding between fields: 1
but I think this is counter-intuitive. Is this how it is supposed to work? I'm on Rust stable 1.57.
To meet the requirements with the available tools, your best option may be to construct a substitute for your u32
field which naturally has an alignment of 1:
#[repr(C, align(4096))]
struct Foo {
first: u8,
second: [u8; 4],
}
impl Foo {
fn second(&self) -> u32 {
u32::from_ne_bytes(self.second)
}
fn set_second(&mut self, value: u32) {
self.second = u32::to_ne_bytes(value);
}
}
This struct's layout passes your tests.
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.