Transmute results in strange order

hi,
I am new to rust and still studying it. I would like to read/write struct from/to binary file and found some peoples use transmute to map an array from/to a struct. However, the result of transmute is in strange order. Here is the code:

use std::mem::{size_of,transmute};
use std::fs::File;

#[derive(Debug)]
struct Header{
byte_order:[u8;2],
magic_value:u16,
offset:u32,
}
fn main() {
let example_header = Header{
byte_order:[1,2],
magic_value:3,
offset:4,
};

let array:[u8;size_of::<Header>()] = unsafe { transmute(example_header) };

println!("{:#?}",array);

}

and the result is :
[
4,
0,
0,
0,
1,
2,
3,
0,
]
any idea?

The layout of types is not guaranteed unless you use something like #[repr(C)] on the type definition to force a specific layout. I did recommend using a crate like bytemuck instead of using std::mem::transmute. Bytemuck verifies that the layout is fixed and doesn't have any padding. As such it allows you to transmute between your type and raw bytes without any unsafe code.

2 Likes

thanks a lot, it works after I put the #[repr(C)].
I will look into the bytemuck as I am still learning how to use 3rd party crate. thank again

I wrote about using this exact trick a while back:

However, in general I would recommend avoiding the "transmute file contents to a struct" method of loading data from disk. It's an unsafe operation for some very good reasons and makes it easy to write code for loading/saving files that is non-portable (i.e. with transmute(), endianness matters) and error-prone (how do you know the file actually contains a Header, not checking your array sizes can result in UB, any pointers you get will be complete garbage, etc.).

Instead, assuming you can't change to a well-specified format (e.g. JSON), I would normally write code for manually loading each object and their fields. A decoder like that tends to be pretty fast to write and has a negligible performance impact.

You can also parse binary formats declaratively using something like the binrw crate.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.