aligned_ptr/
lib.rs

1//! A library to ensure that a pointer is aligned and not null when it dereferences.
2//!
3//! This crate contains wrappers of unsafe functions defined in [`core::ptr`] and [`core::slice`].
4//! These wrappers panic or return errors if the passed pointers are null or not aligned correctly.
5//!
6//! For example, the code below panics because `p` is not aligned correctly.
7//!
8//! ```rust,should_panic
9//! use aligned_ptr::ptr;
10//!
11//! let x = 0xdead_beaf_u32;
12//! let p = (&x as *const u32 as usize + 1) as *const u16;
13//!
14//! unsafe { ptr::read(p) };
15//! ```
16//!
17//! If we import [`core::ptr`] instead of [`ptr`], the code may run successfully.
18//! However, dereferencing unaligned pointer causes *undefined behaviors* and must be avoided
19//! by all means (except [`core::ptr::read_unaligned`] and [`core::ptr::write_unaligned`]).
20//!
21//! # Safety
22//!
23//! While the functions defined in this crate rejects unaligned or null pointers, the caller must
24//! follow the other safety rules. For more information, see the safety note of [`core::ptr`].
25
26#![no_std]
27#![deny(rustdoc::all, unsafe_op_in_unsafe_fn)]
28
29pub mod error;
30pub mod ptr;
31pub mod slice;
32
33pub use error::Error;
34
35/// [`core::result::Result`] which may contain [`Error`].
36pub type Result<T> = core::result::Result<T, Error>;
37
38const ERR_MSG: &str = "Pointer is either null or not aligned.";
39
40fn return_error_on_null_or_misaligned<T>(p: *const T) -> Result<()> {
41    if p.is_null() {
42        Err(Error::Null)
43    } else if is_aligned(p) {
44        Ok(())
45    } else {
46        Err(Error::NotAligned)
47    }
48}
49
50fn is_aligned<T>(p: *const T) -> bool {
51    p as usize % core::mem::align_of::<T>() == 0
52}