Do any of the following cause UB:
mem::transmute::<[u8; 4], [u16; 2]>(..);
mem::transmute::<[f32; 2], f64>(..);
I would have thought not, but I've got it wrong before, especially around mem::uninitialized.
Do any of the following cause UB:
mem::transmute::<[u8; 4], [u16; 2]>(..);
mem::transmute::<[f32; 2], f64>(..);
I would have thought not, but I've got it wrong before, especially around mem::uninitialized.
I believe these are both safe, because:
Generally speaking, I believe the answer is yes, but the results may depend on the individual platform you are compiling for. I would tend to prefer byteorder for the first operation. I'm not sure why you want to convert in the second case, though. It seems like the results are unlikely to be desirable. However, f64::from_bits(a[0].to_bits() as u64 | a[1].to_bits() as u64)
might be clearer (I think it's equivalent).
Signalling NaN?
Relative to the topic of this thread: " Can I transmute between types?",
I don't believe either can cause UB. However, successful transmute
requires more than simply being non-UB. Each of these transmutes may cause an alignment fault on processors where u16
and f64
have more restrictive alignment requirements than u8
and f32
, (e.g., when the [u8; 4]
starts on an odd byte boundary, or the [f32; 2]
starts on a 4 (mod 8)
boundary).
Signaling NaN in Rust has platform-dependent behavior, but not undefined behavior. f64::from_bits can create signaling NaN in safe Rust. Further discussion.
This would be true if the code used a raw pointer cast, but transmute
takes its argument by value and returns a new value. The return value doesn't share the address of the argument value, so transmute
can work without doing any unaligned reads or writes -- at least since the fix in #38670.
There's a missing shift operation here.
Sorry. You are of course correct. I tend to conceptualize transmute as reinterpreting an item in memory, rather than reinterpreting an expression value with no storage connotations.
As transmute
's docs say:
it's best to think of it like a (value) memcpy
.