Summary

Add two functions, ptr::read_unaligned and ptr::write_unaligned, which allows reading/writing to an unaligned pointer. All other functions that access memory (ptr::{read,write}, ptr::copy{_nonoverlapping}, etc) require that a pointer be suitably aligned for its type.

Motivation

One major use case is to make working with packed structs easier:

#[repr(packed)] struct Packed(u8, u16, u8); let mut a = Packed(0, 1, 0); unsafe { let b = ptr::read_unaligned(&a.1); ptr::write_unaligned(&mut a.1, b + 1); }

Other use cases generally involve parsing some file formats or network protocols that use unaligned values.

Detailed design

The implementation of these functions are simple wrappers around ptr::copy_nonoverlapping. The pointers are cast to u8 to ensure that LLVM does not make any assumptions about the alignment.

pub unsafe fn read_unaligned<T>(p: *const T) -> T { let mut r = mem::uninitialized(); ptr::copy_nonoverlapping(p as *const u8, &mut r as *mut _ as *mut u8, mem::size_of::<T>()); r } pub unsafe fn write_unaligned<T>(p: *mut T, v: T) { ptr::copy_nonoverlapping(&v as *const _ as *const u8, p as *mut u8, mem::size_of::<T>()); }

Drawbacks

There functions aren’t strictly necessary since they are just convenience wrappers around ptr::copy_nonoverlapping.

Alternatives

We could simply not add these, however figuring out how to do unaligned access properly is extremely unintuitive: you need to cast the pointer to *mut u8 and then call ptr::copy_nonoverlapping.

Unresolved questions

None