Use of fixed size of <T>

I am providing useful apis for lib users' custom structions. I have to ensure the size of the container A, and I am going to make it easy to transmute the inner into users' types.

Then I make this:

pub struct A {
  pub v1:usize
}
impl A {
  pub fn read<T>(&self)-> T {
    unsafe {transmute(self.v1)}
  }
}

So the compiler tells that T is not fixed sized, and not able to transmute from usize. Can I mark T as usize long?

Note that the types having compatible sizes doesn't guarantee mutation will be defined behavior. Both structs must have identical layout and all values of either type must be valid in the other. Transmutes - The Rustonomicon

Currently there's no way to express this in the type system, see 2835-project-safe-transmute - The Rust RFC Book. In this case I would write a proc macro for the user which will guarantee the types are compatible and implement the transmutation.

3 Likes

Thanks for your patience!

1 Like

It is my fault,,

I think i should just use a box for the inner, why was I thinking about using usize for custom types..

You can use transmute_copy to sidestep the size requirement at compile time. Note that this doesn't guarantee that your function is actually sound. In fact, for most choices of T it won't be, both because its size can be different, and because equal sizes isn't the only validity requirement for sound transmute. This means that your function should likely be unsafe, unless you use some other mechanism to enforce its usage with correct types. E.g. have an unsafe trait Foo which all valid types T must implement, like zerocopy crate does with its FromZeroes trait, or like bytemuck's from_bytes does with AnyBitPattern.

If you can't ensure soundness and must make your function unsafe, at least insert a runtime size assertion

assert_eq!(mem::size_of::<T>(), mem::size_of_val(&self.v1));
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.