DIfference between `transmute` and `as`?


#1

The docs give the following alternative to using transmute:

Turning an &mut T into an &mut U :

let ptr = &mut 0;
let val_transmuted = unsafe {
    std::mem::transmute::<&mut i32, &mut u32>(ptr)
};

// Now, put together `as` and reborrowing - note the chaining of `as`
// `as` is not transitive
let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };

Are they really doing the same thing?


#2

Yes, these are pretty much equivalent. However, transmute can also change the types of non-pointer types and it can also change lifetimes. You can’t do that with as. Since transmute has such power (and therefore potential for misuse), its use is generally not recommend.


#3

transmute is unsafe where as as isn’t :wink:


#4

A bit off-topic, but I hadn’t considered using transmute to change lifetimes before this moment.
Thanks for the idea!


#5

godbolt


#6

In fact as compiles to the same code even at O0, whereas the transmute version needs at least O1 to collapse. It’s rare to care about performance of unoptimized code but debug builds would be that little smidge quicker with as :slight_smile:


#7

Which is the prime reason transmute is unsafe; please practice caution and liberal asserts when doing this! :slight_smile: