Basically, my question is whether the following Rust code can cause UB:
fn usigned_as_signed_ref<'a>(x: &'a u64) -> &'a i64 {
assert!(*x <= i64::MAX as u64);
unsafe { std::mem::transmute(x) }
}
I need it, as I have a struct containing a u64
-value, but I want it to implement an interface that requires returning this value by reference. So if I can't use above code, I would have to store the value twice, once as i64
and once as u64
. In other words, the situation is as follows:
trait ForeignInterface {
fn get_value<'a>(&'a self) -> &'a i64;
}
struct MyStruct(u64);
impl ForeignInterface for MyStruct {
fn get_value<'a>(&'a self) -> &'a i64 { usigned_as_signed_ref(&self.0) }
}
My thoughts so far
I think on a "standard system" (like x86) I expect this to be perfectly safe. In particular, i64
should be represented as two-complement, and the same endianness should be used for u64
and i64
. In fact, I cannot imagine that this is different anywhere. However, I have also made the experience that if something is not guaranteed to work everywhere by the specs, it will fail in weird circumstances. I could not find any guarantee for this to work.
I was not quite sure whether this question fits StackOverflow or CodeReview better, feel free to migrate it if you think otherwise.
Edit This question seems to indicate that it is indeed ok, but does not give any evidence.