Skip to content

Commit a4a6bdd

Browse files
committed
addr_of_mut: add example for creating a pointer to uninit data
1 parent ccd9975 commit a4a6bdd

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

library/core/src/mem/maybe_uninit.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ use crate::ptr;
190190
/// let ptr = uninit.as_mut_ptr();
191191
///
192192
/// // Initializing the `name` field
193+
/// // Using `write` instead of assignment via `=` to not call `drop` on the
194+
/// // old, uninitialized value.
193195
/// unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); }
194196
///
195197
/// // Initializing the `list` field

library/core/src/ptr/mod.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,12 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
15401540
/// let raw_f2 = ptr::addr_of!(packed.f2);
15411541
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
15421542
/// ```
1543+
///
1544+
/// See [`addr_of_mut`] for how to create a pointer to ininitialized data.
1545+
/// Doing that with `addr_of` would not make much sense since one could only
1546+
/// read the data, and that would be Undefined Behavior.
1547+
///
1548+
/// [`addr_of_mut`]: macro.addr_of_mut.html
15431549
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
15441550
#[rustc_macro_transparency = "semitransparent"]
15451551
#[allow_internal_unstable(raw_ref_op)]
@@ -1556,7 +1562,9 @@ pub macro addr_of($place:expr) {
15561562
/// as all other references. This macro can create a raw pointer *without* creating
15571563
/// a reference first.
15581564
///
1559-
/// # Example
1565+
/// # Examples
1566+
///
1567+
/// **Creating a pointer to unaligned data:**
15601568
///
15611569
/// ```
15621570
/// use std::ptr;
@@ -1573,6 +1581,23 @@ pub macro addr_of($place:expr) {
15731581
/// unsafe { raw_f2.write_unaligned(42); }
15741582
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
15751583
/// ```
1584+
///
1585+
/// **Creating a pointer to uninitialized data:**
1586+
///
1587+
/// ```rust
1588+
/// use std::{ptr, mem::MaybeUninit};
1589+
///
1590+
/// struct Demo {
1591+
/// field: bool,
1592+
/// }
1593+
///
1594+
/// let mut uninit = MaybeUninit::<Demo>::uninit();
1595+
/// // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
1596+
/// // and thus be Undefined Behavior!
1597+
/// let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) };
1598+
/// unsafe { f1_ptr.write(true); }
1599+
/// let init = unsafe { uninit.assume_init() };
1600+
/// ```
15761601
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
15771602
#[rustc_macro_transparency = "semitransparent"]
15781603
#[allow_internal_unstable(raw_ref_op)]

0 commit comments

Comments
 (0)