Skip to content

Update ptr::{read,write}_unaligned docs to reference addr_of(_mut) #84778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 45 additions & 8 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,9 +720,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
///
/// ## On `packed` structs
///
/// It is currently impossible to create raw pointers to unaligned fields
/// of a packed struct.
///
/// 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.
Expand All @@ -731,6 +728,28 @@ pub const unsafe fn read<T>(src: *const T) -> T {
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
/// *undefined behavior* in your program.
///
/// To create a pointer to an unaligned struct field safely, instead use
/// [`addr_of!`] to create the pointer to the field without creating an
/// intermediate reference. See [`addr_of!`] for more information.
///
/// An example of how to use [`addr_of!`] and `read_unaligned` to read a
/// pointer to a packed struct field is:
///
/// ```
/// use std::ptr;
///
/// #[repr(packed)]
/// struct Packed {
/// f1: u8,
/// f2: u16,
/// }
///
/// let packed = Packed { f1: 1, f2: 2 };
/// // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
/// let raw_f2 = ptr::addr_of!(packed.f2);
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
/// ```
///
/// An example of what not to do and how this relates to `read_unaligned` is:
///
/// ```no_run
Expand Down Expand Up @@ -762,7 +781,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
/// ```
///
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
// FIXME: Update docs based on outcome of RFC #2582 and friends.
///
/// # Examples
///
Expand Down Expand Up @@ -916,9 +934,6 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
///
/// ## On `packed` structs
///
/// It is currently impossible to create raw pointers to unaligned fields
/// of a packed struct.
///
/// 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.
Expand All @@ -927,6 +942,29 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
/// *undefined behavior* in your program.
///
/// To create a pointer to an unaligned struct field safely, instead use
/// [`addr_of_mut!`] to create the pointer to the field without creating an
/// intermediate reference. See [`addr_of_mut!`] for more information.
///
/// An example of how to use [`addr_of_mut!`] and `write_unaligned` to write to
/// a pointer to a packed struct field is:
///
/// ```
/// 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.
/// ```
///
/// An example of what not to do and how this relates to `write_unaligned` is:
///
/// ```no_run
Expand Down Expand Up @@ -956,7 +994,6 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
/// ```
///
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
// FIXME: Update docs based on outcome of RFC #2582 and friends.
///
/// # Examples
///
Expand Down