Issue with transmute

Hi
I think I don't understand how transmute works, can someone help me.

Here is an example:

use std::mem;

pub struct Foo {
     a: u8,
     b: u32,
 }

 impl Foo {
     fn from_bytes(bytes: [u8; 5]) -> Foo {
         unsafe {
             mem::transmute(bytes)
         }
     }
}
error: transmute called with differently sized types: [u8; 5] (40 bits) to Foo (64 bits) [--explain E0512]
  --> <anon>:15:14
15 |>              mem::transmute(bytes)
   |>              ^^^^^^^^^^^^^^

error: aborting due to previous error

I don't understand why Foo is not 40 bits.Is there something obvious I can't see?

The elements of the struct are padded such that each starts at an address matching that element type's alignment. For more information on padding and alignment, see The Lost Art of Structure Packing . You can force a packed representation using #[repr(packed)]

Literally the case: padding.

Honestly, you shouldn't be touching transmute unless you understand what's really going on under the covers. Not only do you have the size wrong, you shouldn't ever transmute a non-#[repr(C/packed)] struct like that (...except for cases where it turns out to be OK). It's even endian-dependent, which can end up being a nasty surprise for someone down the road.

If you want to convert raw bytes into other values, you should probably look to the byteorder crate, which provide a safe interface for doing this.

1 Like

Thank you both of you!

Maybe this Thread gives you some more ideas to solve your specific case: Best way to get the 3 bytes of a small u32?