Reading raw value unsafely from enum

I'm doing with C interfaces, and I need keep correct types in Rust layer, so i'v got

pub enum Buf {
  U8(Vec<u8>),
  U16(Vec<u16>),
  ...
  F64(Vec<f64>)
}

I need the raw pointer whatever the type of Vec is, but is it formal and reliable to directly read memory from offset of &buf ? Is there any official way to read raw memory of an enum?

macro_rules! mat {($($t:ident)*)=>{{
  use Buf::*;
  match v {
    $(
      $t(v)=> unsafe{std::mem::transmute::<_,usize>(v.as_ptr())}
    )*
  }
}}}
return mat!(U8 U16 U32 U64 I8 I16 I32 I64 F32 F64)

Finally I write this. I hope this is friendly for the compiler.

Rather than unsafe{std::mem::transmute::<_,usize>(v.as_ptr())}, I would prefer v.as_ptr() as usize.

Also keep in mind that if you're going to modify the content of the buffer, you should use v.as_mut_ptr().

1 Like

More generally, I think I would prefer having only a Vec<T=u8> buffer, and then provide an abstraction to convert to different T types after checking that size and alignment allow it.

When all variants have the same layout (as Vec's header does) then you can match on all of them, and it will optimize nicely:

let ptr: *const u8 = match b {
   U8(v) => v.as_ptr().cast(),
   U16(v) => v.as_ptr().cast(),
   ...
   F64(v) => v.as_ptr().cast(),
}

In facts, it's not just a matter of preference, using transmute to turn a pointer into usize (and then casting the usize back and dereferencing it) is undefined behavior. (I don't quite recall if the initial transmute alone was already UB, or only trying to use the result as a memory address.)

Pointer to usize casts (via as operator) have special behavior[1] that ensures that the pointer's target memory location becomes valid to access by-address from any usize value, otherwise pointer provenance[2] would disallow that.


  1. not behavior at run time on your real machine, but behavior in Rust's abstract machine model that's relevant for the compiler to break any code through optimizations ↩︎

  2. for more information take a look through Ralf Jung's Blog posts in pointers like this one ↩︎

2 Likes

Thanks for everyones' idea for reference, I'm taking them carefully!