Version1 (size = 40)
aabbcccc dddd.... eeeeeeee ffffffff ghij....
Version2 (size = 32)
eeeeeeee ffffffff ccccdddd aabbghij
Version3 (size = 32)
ghijaabb ccccdddd eeeeeeee ffffffff
Version4 (size = 40)
aa..cccc eeeeeeee g.bbdddd ffffffff hij.....
Version5 (size = 48)
aah.cccc i....... eeeeeeee g.bbdddd j....... ffffffff
Version6 (size = 56)
aah.cccc i....... eeeeeeee g...dddd j....... ffffffff bb......
Version7 (size = 32)
eeeeeeee ffffffff ccccdddd aabbhigj
Last active
September 28, 2025 16:13
-
-
Save thlorenz/22c65da029f6fd4a8a3562122251af54 to your computer and use it in GitHub Desktop.
Rust struct alignment investigation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use memoffset::offset_of; | |
| use std::mem; | |
| #[repr(C)] | |
| struct Version1 { | |
| a: u16, | |
| b: u16, | |
| c: u32, | |
| d: u32, | |
| e: u64, | |
| f: u64, | |
| g: u8, | |
| h: u8, | |
| i: u8, | |
| j: u8, | |
| } | |
| #[repr(C)] | |
| struct Version2 { | |
| e: u64, | |
| f: u64, | |
| c: u32, | |
| d: u32, | |
| a: u16, | |
| b: u16, | |
| g: u8, | |
| h: u8, | |
| i: u8, | |
| j: u8, | |
| } | |
| #[repr(C)] | |
| struct Version3 { | |
| g: u8, | |
| h: u8, | |
| i: u8, | |
| j: u8, | |
| a: u16, | |
| b: u16, | |
| c: u32, | |
| d: u32, | |
| e: u64, | |
| f: u64, | |
| } | |
| #[repr(C)] | |
| struct Version4 { | |
| a: u16, | |
| c: u32, | |
| e: u64, | |
| g: u8, | |
| b: u16, | |
| d: u32, | |
| f: u64, | |
| h: u8, | |
| i: u8, | |
| j: u8, | |
| } | |
| #[repr(C)] | |
| struct Version5 { | |
| a: u16, | |
| h: u8, | |
| c: u32, | |
| i: u8, | |
| e: u64, | |
| g: u8, | |
| b: u16, | |
| d: u32, | |
| j: u8, | |
| f: u64, | |
| } | |
| #[repr(C)] | |
| struct Version6 { | |
| a: u16, | |
| h: u8, | |
| c: u32, | |
| i: u8, | |
| e: u64, | |
| g: u8, | |
| d: u32, | |
| j: u8, | |
| f: u64, | |
| b: u16, | |
| } | |
| #[allow(unused)] | |
| struct Version7 { | |
| a: u16, | |
| h: u8, | |
| c: u32, | |
| i: u8, | |
| e: u64, | |
| g: u8, | |
| b: u16, | |
| d: u32, | |
| j: u8, | |
| f: u64, | |
| } | |
| /// Draw a layout map for a struct type | |
| fn show_layout<T>(name: &str, fields: &[(&str, usize, usize)]) { | |
| let size = mem::size_of::<T>(); | |
| let mut layout = vec!['.'; size]; // '.' = padding | |
| for (label, offset, width) in fields { | |
| for i in 0..*width { | |
| layout[offset + i] = label.chars().next().unwrap(); | |
| } | |
| } | |
| println!("{name} (size = {size})"); | |
| for (i, ch) in layout.iter().enumerate() { | |
| print!("{ch}"); | |
| if (i + 1) % 8 == 0 { | |
| print!(" "); | |
| } | |
| } | |
| println!("\n"); | |
| } | |
| fn main() { | |
| show_layout::<Version1>( | |
| "Version1", | |
| &[ | |
| ("a", offset_of!(Version1, a), 2), | |
| ("b", offset_of!(Version1, b), 2), | |
| ("c", offset_of!(Version1, c), 4), | |
| ("d", offset_of!(Version1, d), 4), | |
| ("e", offset_of!(Version1, e), 8), | |
| ("f", offset_of!(Version1, f), 8), | |
| ("g", offset_of!(Version1, g), 1), | |
| ("h", offset_of!(Version1, h), 1), | |
| ("i", offset_of!(Version1, i), 1), | |
| ("j", offset_of!(Version1, j), 1), | |
| ], | |
| ); | |
| show_layout::<Version2>( | |
| "Version2", | |
| &[ | |
| ("e", offset_of!(Version2, e), 8), | |
| ("f", offset_of!(Version2, f), 8), | |
| ("c", offset_of!(Version2, c), 4), | |
| ("d", offset_of!(Version2, d), 4), | |
| ("a", offset_of!(Version2, a), 2), | |
| ("b", offset_of!(Version2, b), 2), | |
| ("g", offset_of!(Version2, g), 1), | |
| ("h", offset_of!(Version2, h), 1), | |
| ("i", offset_of!(Version2, i), 1), | |
| ("j", offset_of!(Version2, j), 1), | |
| ], | |
| ); | |
| show_layout::<Version3>( | |
| "Version3", | |
| &[ | |
| ("g", offset_of!(Version3, g), 1), | |
| ("h", offset_of!(Version3, h), 1), | |
| ("i", offset_of!(Version3, i), 1), | |
| ("j", offset_of!(Version3, j), 1), | |
| ("a", offset_of!(Version3, a), 2), | |
| ("b", offset_of!(Version3, b), 2), | |
| ("c", offset_of!(Version3, c), 4), | |
| ("d", offset_of!(Version3, d), 4), | |
| ("e", offset_of!(Version3, e), 8), | |
| ("f", offset_of!(Version3, f), 8), | |
| ], | |
| ); | |
| show_layout::<Version4>( | |
| "Version4", | |
| &[ | |
| ("a", offset_of!(Version4, a), 2), | |
| ("c", offset_of!(Version4, c), 4), | |
| ("e", offset_of!(Version4, e), 8), | |
| ("g", offset_of!(Version4, g), 1), | |
| ("b", offset_of!(Version4, b), 2), | |
| ("d", offset_of!(Version4, d), 4), | |
| ("f", offset_of!(Version4, f), 8), | |
| ("h", offset_of!(Version4, h), 1), | |
| ("i", offset_of!(Version4, i), 1), | |
| ("j", offset_of!(Version4, j), 1), | |
| ], | |
| ); | |
| show_layout::<Version5>( | |
| "Version5", | |
| &[ | |
| ("a", offset_of!(Version5, a), 2), | |
| ("h", offset_of!(Version5, h), 1), | |
| ("c", offset_of!(Version5, c), 4), | |
| ("i", offset_of!(Version5, i), 1), | |
| ("e", offset_of!(Version5, e), 8), | |
| ("g", offset_of!(Version5, g), 1), | |
| ("b", offset_of!(Version5, b), 2), | |
| ("d", offset_of!(Version5, d), 4), | |
| ("j", offset_of!(Version5, j), 1), | |
| ("f", offset_of!(Version5, f), 8), | |
| ], | |
| ); | |
| show_layout::<Version6>( | |
| "Version6", | |
| &[ | |
| ("a", offset_of!(Version6, a), 2), | |
| ("h", offset_of!(Version6, h), 1), | |
| ("c", offset_of!(Version6, c), 4), | |
| ("i", offset_of!(Version6, i), 1), | |
| ("e", offset_of!(Version6, e), 8), | |
| ("g", offset_of!(Version6, g), 1), | |
| ("d", offset_of!(Version6, d), 4), | |
| ("j", offset_of!(Version6, j), 1), | |
| ("f", offset_of!(Version6, f), 8), | |
| ("b", offset_of!(Version6, b), 2), | |
| ], | |
| ); | |
| show_layout::<Version7>( | |
| "Version7", | |
| &[ | |
| ("a", offset_of!(Version7, a), 2), | |
| ("h", offset_of!(Version7, h), 1), | |
| ("c", offset_of!(Version7, c), 4), | |
| ("i", offset_of!(Version7, i), 1), | |
| ("e", offset_of!(Version7, e), 8), | |
| ("g", offset_of!(Version7, g), 1), | |
| ("b", offset_of!(Version7, b), 2), | |
| ("d", offset_of!(Version7, d), 4), | |
| ("j", offset_of!(Version7, j), 1), | |
| ("f", offset_of!(Version7, f), 8), | |
| ], | |
| ); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [package] | |
| name = "memsize" | |
| version = "0.1.0" | |
| edition = "2024" | |
| [dependencies] | |
| memoffset = "0.9.1" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment