Macro sp_std::ptr::addr_of_mut 1.51.0[−][src]
macro_rules! addr_of_mut { => { ... }; }
Expand description
Create a mut
raw pointer to a place, without creating an intermediate reference.
Creating a reference with &
/&mut
is only allowed if the pointer is properly aligned
and points to initialized data. For cases where those requirements do not hold,
raw pointers should be used instead. However, &mut expr as *mut _
creates a reference
before casting it to a raw pointer, and that reference is subject to the same rules
as all other references. This macro can create a raw pointer without creating
a reference first.
Note, however, that the expr
in addr_of_mut!(expr)
is still subject to all
the usual rules. In particular, addr_of_mut!(*ptr::null_mut())
is Undefined
Behavior because it dereferences a null pointer.
Examples
Creating a pointer to unaligned data:
use std::ptr; #[repr(packed)] struct Packed { f1: u8, f2: u16, } let mut packed = Packed { f1: 1, f2: 2 }; // `&mut packed.f2` would create an unaligned reference, and thus be Undefined Behavior! let raw_f2 = ptr::addr_of_mut!(packed.f2); unsafe { raw_f2.write_unaligned(42); } assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
Creating a pointer to uninitialized data:
use std::{ptr, mem::MaybeUninit}; struct Demo { field: bool, } let mut uninit = MaybeUninit::<Demo>::uninit(); // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`, // and thus be Undefined Behavior! let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) }; unsafe { f1_ptr.write(true); } let init = unsafe { uninit.assume_init() };