about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-04-03 19:25:11 +0200
committerRalf Jung <post@ralfj.de>2021-04-03 19:25:11 +0200
commita4a6bdd33771ef4cf87fd1ffc6895ec7060ff898 (patch)
tree07f0728f518e65e9f8aee0d3fbffae145f09b432
parentccd997592bf545fc54a9cce31f1280f833915ba1 (diff)
downloadrust-a4a6bdd33771ef4cf87fd1ffc6895ec7060ff898.tar.gz
rust-a4a6bdd33771ef4cf87fd1ffc6895ec7060ff898.zip
addr_of_mut: add example for creating a pointer to uninit data
-rw-r--r--library/core/src/mem/maybe_uninit.rs2
-rw-r--r--library/core/src/ptr/mod.rs27
2 files changed, 28 insertions, 1 deletions
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 337f0e847bb..64342de6341 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -190,6 +190,8 @@ use crate::ptr;
 ///     let ptr = uninit.as_mut_ptr();
 ///
 ///     // Initializing the `name` field
+///     // Using `write` instead of assignment via `=` to not call `drop` on the
+///     // old, uninitialized value.
 ///     unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); }
 ///
 ///     // Initializing the `list` field
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 6412bd41a8c..f8b124f581c 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1540,6 +1540,12 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
 /// let raw_f2 = ptr::addr_of!(packed.f2);
 /// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
 /// ```
+///
+/// See [`addr_of_mut`] for how to create a pointer to ininitialized data.
+/// Doing that with `addr_of` would not make much sense since one could only
+/// read the data, and that would be Undefined Behavior.
+///
+/// [`addr_of_mut`]: macro.addr_of_mut.html
 #[stable(feature = "raw_ref_macros", since = "1.51.0")]
 #[rustc_macro_transparency = "semitransparent"]
 #[allow_internal_unstable(raw_ref_op)]
@@ -1556,7 +1562,9 @@ pub macro addr_of($place:expr) {
 /// as all other references. This macro can create a raw pointer *without* creating
 /// a reference first.
 ///
-/// # Example
+/// # Examples
+///
+/// **Creating a pointer to unaligned data:**
 ///
 /// ```
 /// use std::ptr;
@@ -1573,6 +1581,23 @@ pub macro addr_of($place:expr) {
 /// 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:**
+///
+/// ```rust
+/// 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() };
+/// ```
 #[stable(feature = "raw_ref_macros", since = "1.51.0")]
 #[rustc_macro_transparency = "semitransparent"]
 #[allow_internal_unstable(raw_ref_op)]