/// value is not necessarily valid to be used to actually access memory.
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
- /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
- /// and destination may *not* overlap.
+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+ /// and destination must *not* overlap.
///
- /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
+ /// For regions of memory which might overlap, use [`copy`] instead.
+ ///
+ /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`].
+ ///
+ /// [`copy`]: ./fn.copy.html
+ /// [`memcpy`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memcpy
///
/// # Safety
///
- /// Beyond requiring that the program must be allowed to access both regions
- /// of memory, it is Undefined Behavior for source and destination to
- /// overlap. Care must also be taken with the ownership of `src` and
- /// `dst`. This method semantically moves the values of `src` into `dst`.
- /// However it does not drop the contents of `dst`, or prevent the contents
- /// of `src` from being dropped or used.
+ /// Behavior is undefined if any of the following conditions are violated:
+ ///
+ /// * Both `src` and `dst` must be [valid].
+ ///
+ /// * Both `src` and `dst` must be properly aligned.
+ ///
+ /// * `src.offset(count)` must be [valid]. In other words, the region of
+ /// memory which begins at `src` and has a length of `count *
+ /// size_of::<T>()` bytes must belong to a single, live allocation.
+ ///
+ /// * `dst.offset(count)` must be [valid]. In other words, the region of
+ /// memory which begins at `dst` and has a length of `count *
+ /// size_of::<T>()` bytes must belong to a single, live allocation.
+ ///
+ /// * The two regions of memory must *not* overlap.
+ ///
+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
+ /// in the region beginning at `*src` and the region beginning at `*dst` can
+ /// [violate memory safety][read-ownership].
+ ///
+ /// [`Copy`]: ../marker/trait.Copy.html
+ /// [`read`]: ../ptr/fn.read.html
+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
+ /// [valid]: ../ptr/index.html#safety
///
/// # Examples
///
- /// A safe swap function:
+ /// Manually implement [`Vec::append`]:
///
/// ```
- /// use std::mem;
/// use std::ptr;
///
- /// # #[allow(dead_code)]
- /// fn swap<T>(x: &mut T, y: &mut T) {
+ /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
+ /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
+ /// let src_len = src.len();
+ /// let dst_len = dst.len();
+ ///
+ /// // Ensure that `dst` has enough capacity to hold all of `src`.
+ /// dst.reserve(src_len);
+ ///
/// unsafe {
- /// // Give ourselves some scratch space to work with
- /// let mut t: T = mem::uninitialized();
+ /// // The call to offset is always safe because `Vec` will never
+ /// // allocate more than `isize::MAX` bytes.
+ /// let dst = dst.as_mut_ptr().offset(dst_len as isize);
+ /// let src = src.as_ptr();
+ ///
+ /// // The two regions cannot overlap becuase mutable references do
+ /// // not alias, and two different vectors cannot own the same
+ /// // memory.
+ /// ptr::copy_nonoverlapping(src, dst, src_len);
+ /// }
///
- /// // Perform the swap, `&mut` pointers never alias
- /// ptr::copy_nonoverlapping(x, &mut t, 1);
- /// ptr::copy_nonoverlapping(y, x, 1);
- /// ptr::copy_nonoverlapping(&t, y, 1);
+ /// unsafe {
+ /// // Truncate `src` without dropping its contents.
+ /// src.set_len(0);
///
- /// // y and t now point to the same thing, but we need to completely forget `t`
- /// // because it's no longer relevant.
- /// mem::forget(t);
+ /// // Notify `dst` that it now holds the contents of `src`.
+ /// dst.set_len(dst_len + src_len);
/// }
/// }
+ ///
+ /// let mut a = vec!['r'];
+ /// let mut b = vec!['u', 's', 't'];
+ ///
+ /// append(&mut a, &mut b);
+ ///
+ /// assert_eq!(a, &['r', 'u', 's', 't']);
+ /// assert!(b.is_empty());
/// ```
+ ///
+ /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
- /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
/// and destination may overlap.
///
- /// `copy` is semantically equivalent to C's `memmove`.
+ /// If the source and destination will *never* overlap,
+ /// [`copy_nonoverlapping`] can be used instead.
+ ///
+ /// `copy` is semantically equivalent to C's [`memmove`].
+ ///
+ /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
+ /// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove
///
/// # Safety
///
- /// Care must be taken with the ownership of `src` and `dst`.
- /// This method semantically moves the values of `src` into `dst`.
- /// However it does not drop the contents of `dst`, or prevent the contents of `src`
- /// from being dropped or used.
+ /// Behavior is undefined if any of the following conditions are violated:
+ ///
+ /// * Both `src` and `dst` must be [valid].
+ ///
+ /// * Both `src` and `dst` must be properly aligned.
+ ///
+ /// * `src.offset(count)` must be [valid]. In other words, the region of
+ /// memory which begins at `src` and has a length of `count *
+ /// size_of::<T>()` bytes must belong to a single, live allocation.
+ ///
+ /// * `dst.offset(count)` must be [valid]. In other words, the region of
+ /// memory which begins at `dst` and has a length of `count *
+ /// size_of::<T>()` bytes must belong to a single, live allocation.
+ ///
+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
+ /// in the region beginning at `*src` and the region beginning at `*dst` can
+ /// [violate memory safety][read-ownership].
+ ///
+ /// [`Copy`]: ../marker/trait.Copy.html
+ /// [`read`]: ../ptr/fn.read.html
+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
+ /// [valid]: ../ptr/index.html#safety
///
/// # Examples
///
/// dst
/// }
/// ```
- ///
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
- /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
- /// bytes of memory starting at `dst` to `val`.
+ /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
+ /// `val`.
+ ///
+ /// `write_bytes` is similar to C's [`memset`], but sets `count *
+ /// size_of::<T>()` bytes to `val`.
+ ///
+ /// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset
+ ///
+ /// # Safety
+ ///
+ /// Behavior is undefined if any of the following conditions are violated:
+ ///
+ /// * `dst` must be [valid].
+ ///
+ /// * `dst.offset(count)` must be [valid]. In other words, the region of
+ /// memory which begins at `dst` and has a length of `count *
+ /// size_of::<T>()` bytes must belong to a single, live allocation.
+ ///
+ /// * `dst` must be properly aligned.
+ ///
+ /// Additionally, the caller must ensure that writing `count *
+ /// size_of::<T>()` bytes to the given region of memory results in a valid
+ /// value of `T`. Creating an invalid value of `T` can result in undefined
+ /// behavior.
+ ///
+ /// [valid]: ../ptr/index.html#safety
///
/// # Examples
///
+ /// Basic usage:
+ ///
/// ```
/// use std::ptr;
///
- /// let mut vec = vec![0; 4];
+ /// let mut vec = vec![0u32; 4];
/// unsafe {
/// let vec_ptr = vec.as_mut_ptr();
- /// ptr::write_bytes(vec_ptr, b'a', 2);
+ /// ptr::write_bytes(vec_ptr, 0xfe, 2);
/// }
- /// assert_eq!(vec, [b'a', b'a', 0, 0]);
+ /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
+ /// ```
+ ///
+ /// Creating an invalid value:
+ ///
+ /// ```no_run
+ /// use std::{mem, ptr};
+ ///
+ /// let mut v = Box::new(0i32);
+ ///
+ /// unsafe {
+ /// // Leaks the previously held value by overwriting the `Box<T>` with
+ /// // a null pointer.
+ /// ptr::write_bytes(&mut v, 0, 1);
+ /// }
+ ///
+ /// // At this point, using or dropping `v` results in undefined behavior.
+ /// // v = Box::new(0i32); // ERROR
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
-//! Raw, unsafe pointers, `*const T`, and `*mut T`.
+//! Manually manage memory through raw pointers.
//!
//! *[See also the pointer primitive types](../../std/primitive.pointer.html).*
+//!
+//! # Safety
+//!
+//! Most functions in this module [dereference raw pointers].
+//!
+//! In order for a pointer dereference to be safe, the pointer must be "valid".
+//! A valid pointer is one that satisfies **all** of the following conditions:
+//!
+//! * The pointer is not null.
+//! * The pointer is not dangling (it does not point to memory which has been
+//! freed).
+//! * The pointer satisfies [LLVM's pointer aliasing rules].
+//!
+//! [dereference raw pointers]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
+//! [LLVM's pointer aliasing rules]: https://llvm.org/docs/LangRef.html#pointer-aliasing-rules
#![stable(feature = "rust1", since = "1.0.0")]
/// Executes the destructor (if any) of the pointed-to value.
///
-/// This has two use cases:
+/// This is semantically equivalent to calling [`ptr::read`] and discarding
+/// the result, but has the following advantages:
///
/// * It is *required* to use `drop_in_place` to drop unsized types like
/// trait objects, because they can't be read out onto the stack and
/// dropped normally.
///
-/// * It is friendlier to the optimizer to do this over `ptr::read` when
+/// * It is friendlier to the optimizer to do this over [`ptr::read`] when
/// dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
/// as the compiler doesn't need to prove that it's sound to elide the
/// copy.
///
+/// [`ptr::read`]: ../ptr/fn.read.html
+///
/// # Safety
///
-/// This has all the same safety problems as `ptr::read` with respect to
-/// invalid pointers, types, and double drops.
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `to_drop` must be [valid].
+///
+/// * `to_drop` must be properly aligned.
+///
+/// Additionally, if `T` is not [`Copy`], using the pointed-to value after
+/// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
+/// foo` counts as a use because it will cause the the value to be dropped
+/// again. [`write`] can be used to overwrite data without causing it to be
+/// dropped.
+///
+/// [valid]: ../ptr/index.html#safety
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`write`]: ../ptr/fn.write.html
+///
+/// # Examples
+///
+/// Manually remove the last item from a vector:
+///
+/// ```
+/// use std::ptr;
+/// use std::rc::Rc;
+///
+/// let last = Rc::new(1);
+/// let weak = Rc::downgrade(&last);
+///
+/// let mut v = vec![Rc::new(0), last];
+///
+/// unsafe {
+/// // Without a call `drop_in_place`, the last item would never be dropped,
+/// // and the memory it manages would be leaked.
+/// ptr::drop_in_place(&mut v[1]);
+/// v.set_len(1);
+/// }
+///
+/// assert_eq!(v, &[0.into()]);
+///
+/// // Ensure that the last item was dropped.
+/// assert!(weak.upgrade().is_none());
+/// ```
#[stable(feature = "drop_in_place", since = "1.8.0")]
#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
/// Swaps the values at two mutable locations of the same type, without
/// deinitializing either.
///
-/// The values pointed at by `x` and `y` may overlap, unlike `mem::swap` which
-/// is otherwise equivalent. If the values do overlap, then the overlapping
-/// region of memory from `x` will be used. This is demonstrated in the
-/// examples section below.
+/// But for the following two exceptions, this function is semantically
+/// equivalent to [`mem::swap`]:
+///
+/// * It operates on raw pointers instead of references. When references are
+/// available, [`mem::swap`] should be preferred.
+///
+/// * The two pointed-to values may overlap. If the values do overlap, then the
+/// overlapping region of memory from `x` will be used. This is demonstrated
+/// in the examples below.
+///
+/// [`mem::swap`]: ../mem/fn.swap.html
///
/// # Safety
///
-/// This function copies the memory through the raw pointers passed to it
-/// as arguments.
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * Both `x` and `y` must be [valid].
///
-/// Ensure that these pointers are valid before calling `swap`.
+/// * Both `x` and `y` must be properly aligned.
+///
+/// [valid]: ../ptr/index.html#safety
///
/// # Examples
///
///
/// Neither value is dropped.
///
+/// This function is semantically equivalent to [`mem::replace`] except that it
+/// operates on raw pointers instead of references. When references are
+/// available, [`mem::replace`] should be preferred.
+///
+/// [`mem::replace`]: ../mem/fn.replace.html
+///
/// # Safety
///
-/// This is only unsafe because it accepts a raw pointer.
-/// Otherwise, this operation is identical to `mem::replace`.
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `dest` must be [valid].
+///
+/// * `dest` must be properly aligned.
+///
+/// [valid]: ../ptr/index.html#safety
+///
+/// # Examples
+///
+/// ```
+/// use std::ptr;
+///
+/// let mut rust = vec!['b', 'u', 's', 't'];
+///
+/// // `mem::replace` would have the same effect without requiring the unsafe
+/// // block.
+/// let b = unsafe {
+/// ptr::replace(&mut rust[0], 'r')
+/// };
+///
+/// assert_eq!(b, 'b');
+/// assert_eq!(rust, &['r', 'u', 's', 't']);
+/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
///
/// # Safety
///
-/// Beyond accepting a raw pointer, this is unsafe because it semantically
-/// moves the value out of `src` without preventing further usage of `src`.
-/// If `T` is not `Copy`, then care must be taken to ensure that the value at
-/// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
-/// because it will attempt to drop the value previously at `*src`.
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid].
+///
+/// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the
+/// case.
+///
+/// ## Ownership of the Returned Value
+///
+/// `read` 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 assigning to `src` counts as a
+/// use because it will attempt to drop the value at `*src`.
+///
+/// [`write`] can be used to overwrite data without causing it to be dropped.
+///
+/// [valid]: ../ptr/index.html#safety
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`read_unaligned`]: ./fn.read_unaligned.html
+/// [`write`]: ./fn.write.html
+///
+/// ```
+/// use std::ptr;
+///
+/// let mut s = String::new("foo");
+/// unsafe {
+/// // `s2` now points to the same underlying memory as `s1`.
+/// let mut s2 = ptr::read(&s);
+///
+/// assert_eq!(s2, "foo");
+///
+/// // Assigning to `s2` causes its original value to be dropped. Beyond
+/// // this point, `s` must no longer be used, as the underlying memory has
+/// // been freed.
+/// s2 = String::default();
///
-/// The pointer must be aligned; use `read_unaligned` if that is not the case.
+/// // Assigning to `s` would cause the old value to be dropped again,
+/// // resulting in undefined behavior.
+/// // s = String::new("bar"); // ERROR
+///
+/// // `ptr::write` can be used to overwrite a value without dropping it.
+/// ptr::write(&s, String::new("bar"));
+/// }
+///
+/// assert_eq!(s, "bar");
+/// ```
///
/// # Examples
///
/// assert_eq!(std::ptr::read(y), 12);
/// }
/// ```
+///
+/// Manually implement [`mem::swap`]:
+///
+/// ```
+/// use std::ptr;
+///
+/// fn swap<T>(a: &mut T, b: &mut T) {
+/// unsafe {
+/// // Create a bitwise copy of the value at `a` in `tmp`.
+/// let tmp = ptr::read(a);
+///
+/// // Exiting at this point (either by explicitly returning or by
+/// // calling a function which panics) would cause the value in `tmp` to
+/// // be dropped while the same value is still referenced by `a`. This
+/// // could trigger undefined behavior if `T` is not `Copy`.
+///
+/// // Create a bitwise copy of the value at `b` in `a`.
+/// // This is safe because mutable references cannot alias.
+/// ptr::copy_nonoverlapping(b, a, 1);
+///
+/// // As above, exiting here could trigger undefined behavior because
+/// // the same value is referenced by `a` and `b`.
+///
+/// // Move `tmp` into `b`.
+/// ptr::write(b, tmp);
+/// }
+/// }
+///
+/// let mut foo = "foo".to_owned();
+/// let mut bar = "bar".to_owned();
+///
+/// swap(&mut foo, &mut bar);
+///
+/// assert_eq!(foo, "bar");
+/// assert_eq!(bar, "foo");
+/// ```
+///
+/// [`mem::swap`]: ../mem/fn.swap.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn read<T>(src: *const T) -> T {
/// Reads the value from `src` without moving it. This leaves the
/// memory in `src` unchanged.
///
-/// Unlike `read`, the pointer may be unaligned.
+/// Unlike [`read`], `read_unaligned` works with unaligned pointers.
///
/// # Safety
///
-/// Beyond accepting a raw pointer, this is unsafe because it semantically
-/// moves the value out of `src` without preventing further usage of `src`.
-/// If `T` is not `Copy`, then care must be taken to ensure that the value at
-/// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
-/// because it will attempt to drop the value previously at `*src`.
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid].
+///
+/// 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][read-ownership].
+///
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`read`]: ./fn.read.html
+/// [`write_unaligned`]: ./fn.write_unaligned.html
+/// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
+/// [valid]: ../ptr/index.html#safety
///
/// # Examples
///
-/// Basic usage:
+/// Access members of a packed struct by reference:
///
/// ```
-/// let x = 12;
-/// let y = &x as *const i32;
+/// use std::ptr;
///
-/// unsafe {
-/// assert_eq!(std::ptr::read_unaligned(y), 12);
+/// #[repr(packed, C)]
+/// #[derive(Default)]
+/// struct Packed {
+/// _padding: u8,
+/// unaligned: u32,
/// }
+///
+/// let x = Packed {
+/// _padding: 0x00,
+/// unaligned: 0x01020304,
+/// };
+///
+/// let v = unsafe {
+/// // Take a reference to a 32-bit integer which is not aligned.
+/// let unaligned = &x.unaligned;
+///
+/// // Dereferencing normally will emit an unaligned load instruction,
+/// // causing undefined behavior.
+/// // let v = *unaligned; // ERROR
+///
+/// // Instead, use `read_unaligned` to read improperly aligned values.
+/// let v = ptr::read_unaligned(unaligned);
+///
+/// v
+/// };
+///
+/// // Accessing unaligned values directly is safe.
+/// assert!(x.unaligned == v);
/// ```
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
/// Overwrites a memory location with the given value without reading or
/// dropping the old value.
///
-/// # Safety
-///
-/// This operation is marked unsafe because it accepts a raw pointer.
-///
-/// It does not drop the contents of `dst`. This is safe, but it could leak
+/// `write` does not drop the contents of `dst`. This is safe, but it could leak
/// allocations or resources, so care must be taken not to overwrite an object
/// that should be dropped.
///
/// location pointed to by `dst`.
///
/// This is appropriate for initializing uninitialized memory, or overwriting
-/// memory that has previously been `read` from.
+/// memory that has previously been [`read`] from.
///
-/// The pointer must be aligned; use `write_unaligned` if that is not the case.
+/// [`read`]: ./fn.read.html
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `dst` must be [valid].
+///
+/// * `dst` must be properly aligned. Use [`write_unaligned`] if this is not the
+/// case.
+///
+/// [valid]: ../ptr/index.html#safety
+/// [`write_unaligned`]: ./fn.write_unaligned.html
///
/// # Examples
///
/// assert_eq!(std::ptr::read(y), 12);
/// }
/// ```
+///
+/// Manually implement [`mem::swap`]:
+///
+/// ```
+/// use std::ptr;
+///
+/// fn swap<T>(a: &mut T, b: &mut T) {
+/// unsafe {
+/// let tmp = ptr::read(a);
+/// ptr::copy_nonoverlapping(b, a, 1);
+/// ptr::write(b, tmp);
+/// }
+/// }
+///
+/// let mut foo = "foo".to_owned();
+/// let mut bar = "bar".to_owned();
+///
+/// swap(&mut foo, &mut bar);
+///
+/// assert_eq!(foo, "bar");
+/// assert_eq!(bar, "foo");
+/// ```
+///
+/// [`mem::swap`]: ../mem/fn.swap.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn write<T>(dst: *mut T, src: T) {
/// Overwrites a memory location with the given value without reading or
/// dropping the old value.
///
-/// Unlike `write`, the pointer may be unaligned.
-///
-/// # Safety
+/// Unlike [`write`], the pointer may be unaligned.
///
-/// This operation is marked unsafe because it accepts a raw pointer.
-///
-/// It does not drop the contents of `dst`. This is safe, but it could leak
-/// allocations or resources, so care must be taken not to overwrite an object
-/// that should be dropped.
+/// `write_unaligned` does not drop the contents of `dst`. This is safe, but it
+/// could leak allocations or resources, so care must be taken not to overwrite
+/// an object that should be dropped.
///
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
/// location pointed to by `dst`.
///
/// This is appropriate for initializing uninitialized memory, or overwriting
-/// memory that has previously been `read` from.
+/// memory that has previously been read with [`read_unaligned`].
+///
+/// [`write`]: ./fn.write.html
+/// [`read_unaligned`]: ./fn.read_unaligned.html
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `dst` must be [valid].
+///
+/// [valid]: ../ptr/index.html#safety
///
/// # Examples
///
-/// Basic usage:
+/// Access fields in a packed struct:
///
/// ```
-/// let mut x = 0;
-/// let y = &mut x as *mut i32;
-/// let z = 12;
+/// use std::{mem, ptr};
+///
+/// #[repr(packed, C)]
+/// #[derive(Default)]
+/// struct Packed {
+/// _padding: u8,
+/// unaligned: u32,
+/// }
+///
+/// let v = 0x01020304;
+/// let mut x: Packed = unsafe { mem::zeroed() };
///
/// unsafe {
-/// std::ptr::write_unaligned(y, z);
-/// assert_eq!(std::ptr::read_unaligned(y), 12);
+/// // Take a reference to a 32-bit integer which is not aligned.
+/// let unaligned = &mut x.unaligned;
+///
+/// // Dereferencing normally will emit an unaligned store instruction,
+/// // causing undefined behavior.
+/// // *unaligned = v; // ERROR
+///
+/// // Instead, use `write_unaligned` to write improperly aligned values.
+/// ptr::write_unaligned(unaligned, v);
/// }
-/// ```
+///
+/// // Accessing unaligned values directly is safe.
+/// assert!(x.unaligned == v);
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
/// to not be elided or reordered by the compiler across other volatile
/// operations.
///
+/// Memory read with `read_volatile` should almost always be written to using
+/// [`write_volatile`].
+///
+/// [`write_volatile`]: ./fn.write_volatile.html
+///
/// # Notes
///
/// Rust does not currently have a rigorously and formally defined memory model,
///
/// # Safety
///
-/// Beyond accepting a raw pointer, this is unsafe because it semantically
-/// moves the value out of `src` without preventing further usage of `src`.
-/// If `T` is not `Copy`, then care must be taken to ensure that the value at
-/// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
-/// because it will attempt to drop the value previously at `*src`.
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid].
+///
+/// * `src` must be properly aligned.
+///
+/// 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][read-ownership].
+/// However, storing non-[`Copy`] types in volatile memory is almost certainly
+/// incorrect.
+///
+/// [valid]: ../ptr/index.html#safety
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`read`]: ./fn.read.html
///
/// Just like in C, whether an operation is volatile has no bearing whatsoever
/// on questions involving concurrent access from multiple threads. Volatile
/// to not be elided or reordered by the compiler across other volatile
/// operations.
///
+/// Memory written with `write_volatile` should almost always be read from using
+/// [`read_volatile`].
+///
+/// `write_volatile` does not drop the contents of `dst`. This is safe, but it
+/// could leak allocations or resources, so care must be taken not to overwrite
+/// an object that should be dropped.
+///
+/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
+/// location pointed to by `dst`.
+///
+/// [`read_volatile`]: ./fn.read_volatile.html
+///
/// # Notes
///
/// Rust does not currently have a rigorously and formally defined memory model,
///
/// # Safety
///
-/// This operation is marked unsafe because it accepts a raw pointer.
+/// Behavior is undefined if any of the following conditions are violated:
///
-/// It does not drop the contents of `dst`. This is safe, but it could leak
-/// allocations or resources, so care must be taken not to overwrite an object
-/// that should be dropped.
+/// * `dst` must be [valid].
///
-/// This is appropriate for initializing uninitialized memory, or overwriting
-/// memory that has previously been `read` from.
+/// * `dst` must be properly aligned.
+///
+/// [valid]: ../ptr/index.html#safety
///
/// Just like in C, whether an operation is volatile has no bearing whatsoever
/// on questions involving concurrent access from multiple threads. Volatile