Skip to main content

read_unaligned

Function read_unaligned 

1.17.0 (const: 1.71.0) · Source
pub const unsafe fn read_unaligned<T>(src: *const T) -> T
This item is validated for IEC 61508 (SIL 2) and ISO 26262 (ASIL B).
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 type T.

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.

§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 &raw const syntax to create the pointer. You may use that constructed 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 = &raw const 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:

fn read_usize(x: &[u8]) -> usize {
    assert!(x.len() >= size_of::<usize>());

    let ptr = x.as_ptr() as *const usize;

    unsafe { ptr.read_unaligned() }
}