from the type system's perspective, it is not a valid safe pointer, although the address may be within "bounds" and well-aligned.
even if assuming the address is good, you should only use raw pointers to avoid UB, and that's why offset_of!()
and/or addr_of!()
exsit. , and you should NOT access it via the "normal" field access syntax, which is a place expression, to quote the reference:
Implicit borrows may be taken in the following expressions:
- ...
- Left operand in field expressions.
- ...
I don't know what you mean exactly, but MaybeUninit
can eliminate uninitialized memory related UB when used correctly (well, it more or less forces you to use raw pointers all over the place).
if you mean something like
union U {
s: MaybeUninit<String>,
}
// or even
union U {
s: MaybeUninit<ManuallyDrop<String>>,
}
then you are right, rust does not support this, rust requires all the variants of a union
to be either Copy
, or ManuallyDrop
, or references.
well, if you are doing type punning, then you are essentially cheating the type checker, so you cannot get away without unsafe
. all the type punning methods in rust need unsafe
, in one way or another. e.g. transmute()
is an unsafe
function, and raw pointers also need unsafe
when you access the pointee, ffi
functions are always unsafe
, etc.
just a reminder, type punning for types that are neither #[repr(C)]
nor #[repr(transparent)]
(and not primitive scalar types, obviously) is too easy to be unsound. remember, structs (and unions!!!) don't have a specified memory layout unless annotated with #[repr(...)]
attribute. it's really easy to (accidentally) access padding bytes in types.