Skip to content

Commit fbe89e2

Browse files
authored
Rollup merge of #83815 - RalfJung:addr_of, r=kennytm
ptr::addr_of documentation improvements While writing rust-lang/reference#1001 I figured I could also improve the docs here a bit.
2 parents ad776fd + b577d7e commit fbe89e2

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

library/core/src/mem/maybe_uninit.rs

+2
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

+32-1
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,10 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
15371537
/// as all other references. This macro can create a raw pointer *without* creating
15381538
/// a reference first.
15391539
///
1540+
/// Note, however, that the `expr` in `addr_of!(expr)` is still subject to all
1541+
/// the usual rules. In particular, `addr_of!(*ptr::null())` is Undefined
1542+
/// Behavior because it dereferences a NULL pointer.
1543+
///
15401544
/// # Example
15411545
///
15421546
/// ```
@@ -1553,6 +1557,10 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
15531557
/// let raw_f2 = ptr::addr_of!(packed.f2);
15541558
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
15551559
/// ```
1560+
///
1561+
/// See [`addr_of_mut`] for how to create a pointer to unininitialized data.
1562+
/// Doing that with `addr_of` would not make much sense since one could only
1563+
/// read the data, and that would be Undefined Behavior.
15561564
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
15571565
#[rustc_macro_transparency = "semitransparent"]
15581566
#[allow_internal_unstable(raw_ref_op)]
@@ -1569,7 +1577,13 @@ pub macro addr_of($place:expr) {
15691577
/// as all other references. This macro can create a raw pointer *without* creating
15701578
/// a reference first.
15711579
///
1572-
/// # Example
1580+
/// Note, however, that the `expr` in `addr_of_mut!(expr)` is still subject to all
1581+
/// the usual rules. In particular, `addr_of_mut!(*ptr::null_mut())` is Undefined
1582+
/// Behavior because it dereferences a NULL pointer.
1583+
///
1584+
/// # Examples
1585+
///
1586+
/// **Creating a pointer to unaligned data:**
15731587
///
15741588
/// ```
15751589
/// use std::ptr;
@@ -1586,6 +1600,23 @@ pub macro addr_of($place:expr) {
15861600
/// unsafe { raw_f2.write_unaligned(42); }
15871601
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
15881602
/// ```
1603+
///
1604+
/// **Creating a pointer to uninitialized data:**
1605+
///
1606+
/// ```rust
1607+
/// use std::{ptr, mem::MaybeUninit};
1608+
///
1609+
/// struct Demo {
1610+
/// field: bool,
1611+
/// }
1612+
///
1613+
/// let mut uninit = MaybeUninit::<Demo>::uninit();
1614+
/// // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
1615+
/// // and thus be Undefined Behavior!
1616+
/// let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) };
1617+
/// unsafe { f1_ptr.write(true); }
1618+
/// let init = unsafe { uninit.assume_init() };
1619+
/// ```
15891620
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
15901621
#[rustc_macro_transparency = "semitransparent"]
15911622
#[allow_internal_unstable(raw_ref_op)]

0 commit comments

Comments
 (0)