pub const unsafe extern "rust-intrinsic" fn transmute<Src, Dst>(
src: Src,
) -> Dst
Expand description
Reinterprets the bits of a value of one type as another type.
Both types must have the same size. Compilation will fail if this is not guaranteed.
transmute
is semantically equivalent to a bitwise move of one type
into another. It copies the bits from the source value into the
destination value, then forgets the original. Note that source and destination
are passed by-value, which means if Src
or Dst
contain padding, that padding
is not guaranteed to be preserved by transmute
.
Both the argument and the result must be valid at
their given type. Violating this condition leads to undefined behavior. The compiler
will generate code assuming that you, the programmer, ensure that there will never be
undefined behavior. It is therefore your responsibility to guarantee that every value
passed to transmute
is valid at both types Src
and Dst
. Failing to uphold this condition
may lead to unexpected and unstable compilation results. This makes transmute
incredibly
unsafe. transmute
should be the absolute last resort.
Because transmute
is a by-value operation, alignment of the transmuted values
themselves is not a concern. As with any other function, the compiler already ensures
both Src
and Dst
are properly aligned. However, when transmuting values that point
elsewhere (such as pointers, references, boxes…), the caller has to ensure proper
alignment of the pointed-to values.
The nomicon has additional documentation.
§Transmutation between pointers and integers
Special care has to be taken when transmuting between pointers and integers, e.g.
transmuting between *const ()
and usize
.
Transmuting pointers to integers in a const
context is undefined behavior, unless
the pointer was originally created from an integer. (That includes this function
specifically, integer-to-pointer casts, and helpers like dangling
,
but also semantically-equivalent conversions such as punning through repr(C)
union
fields.) Any attempt to use the resulting value for integer operations will abort
const-evaluation. (And even outside const
, such transmutation is touching on many
unspecified aspects of the Rust memory model and should be avoided. See below for
alternatives.)
Transmuting integers to pointers is a largely unspecified operation. It is likely not
equivalent to an as
cast. Doing non-zero-sized memory accesses with a pointer constructed
this way is currently considered undefined behavior.
All this also applies when the integer is nested inside an array, tuple, struct, or enum.
However, MaybeUninit<usize>
is not considered an integer type for the purpose of this
section. Transmuting *const ()
to MaybeUninit<usize>
is fine—but then calling
assume_init()
on that result is considered as completing the pointer-to-integer transmute
and thus runs into the issues discussed above.
In particular, doing a pointer-to-integer-to-pointer roundtrip via transmute
is not a
lossless process. If you want to round-trip a pointer through an integer in a way that you
can get back the original pointer, you need to use as
casts, or replace the integer type
by MaybeUninit<$int>
(and never call assume_init()
). If you are looking for a way to
store data of arbitrary type, also use MaybeUninit<T>
(that wil