Function no_std_compat::ptr::read_unaligned
1.17.0 (const: 1.71.0) · source · pub const unsafe fn read_unaligned<T>(src: *const T) -> T
Expand description
Reads the value from src
without moving it. This leaves the
memory in src
unchanged.
Unlike read
, read_unaligned
works with unaligned pointers.
§Safety
Behavior is undefined if any of the following conditions are violated:
-
src
must be valid for reads. -
src
must point to a properly initialized value of typeT
.
Like read
, read_unaligned
creates a bitwise copy of T
, regardless of
whether T
is Copy
. If T
is not Copy
, using both the returned
value and the value at *src
can violate memory safety.
Note that even if T
has size 0
, the pointer must be non-null.
§On packed
structs
Attempting to create a raw pointer to an unaligned
struct field with
an expression such as &packed.unaligned as *const FieldType
creates an
intermediate unaligned reference before converting that to a raw pointer.
That this reference is temporary and immediately cast is inconsequential
as the compiler always expects references to be properly aligned.
As a result, using &packed.unaligned as *const FieldType
causes immediate
undefined behavior in your program.
Instead you must use the ptr::addr_of!
macro to
create the pointer. You may use that returned pointer together with this
function.
An example of what not to do and how this relates to read_unaligned
is:
#[repr(packed, C)]
struct Packed {
_padding: u8,
unaligned: u32,
}
let packed = Packed {
_padding: 0x00,
unaligned: 0x01020304,
};
// Take the address of a 32-bit integer which is not aligned.
// In contrast to `&packed.unaligned as *const _`, this has no undefined behavior.
let unaligned = std::ptr::addr_of!(packed.unaligned);
let v = unsafe { std::ptr::read_unaligned(unaligned) };
assert_eq!(v, 0x01020304);
Accessing unaligned fields directly with e.g. packed.unaligned
is safe however.
§Examples
Read a usize value from a byte buffer:
use std::mem;
fn read_usize(x: &[u8]) -> usize {
assert!(x.len() >= mem::size_of::<usize>());
let ptr = x.as_ptr() as *const usize;
unsafe { ptr.read_unaligned() }
}