@@ -2566,14 +2566,23 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
2566
2566
///
2567
2567
/// * `dst` must be properly aligned.
2568
2568
///
2569
- /// Additionally, the caller must ensure that writing `count *
2570
- /// size_of::<T>()` bytes to the given region of memory results in a valid
2571
- /// value of `T`. Using a region of memory typed as a `T` that contains an
2572
- /// invalid value of `T` is undefined behavior.
2573
- ///
2574
2569
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
2575
2570
/// `0`, the pointer must be non-null and properly aligned.
2576
2571
///
2572
+ /// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB)
2573
+ /// later if the written bytes are not a valid representation of some `T`. For instance, the
2574
+ /// following is an **incorrect** use of this function:
2575
+ ///
2576
+ /// ```rust,no_run
2577
+ /// unsafe {
2578
+ /// let mut value: u8 = 0;
2579
+ /// let ptr: *mut bool = &mut value as *mut u8 as *mut bool;
2580
+ /// let _bool = ptr.read(); // This is fine, `ptr` points to a valid `bool`.
2581
+ /// ptr.write_bytes(42u8, 1); // This function itself does not cause UB...
2582
+ /// let _bool = ptr.read(); // ...but it makes this operation UB! ⚠️
2583
+ /// }
2584
+ /// ```
2585
+ ///
2577
2586
/// [valid]: crate::ptr#safety
2578
2587
///
2579
2588
/// # Examples
@@ -2590,38 +2599,6 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
2590
2599
/// }
2591
2600
/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
2592
2601
/// ```
2593
- ///
2594
- /// Creating an invalid value:
2595
- ///
2596
- /// ```
2597
- /// use std::ptr;
2598
- ///
2599
- /// let mut v = Box::new(0i32);
2600
- ///
2601
- /// unsafe {
2602
- /// // Leaks the previously held value by overwriting the `Box<T>` with
2603
- /// // a null pointer.
2604
- /// ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
2605
- /// }
2606
- ///
2607
- /// // At this point, using or dropping `v` results in undefined behavior.
2608
- /// // drop(v); // ERROR
2609
- ///
2610
- /// // Even leaking `v` "uses" it, and hence is undefined behavior.
2611
- /// // mem::forget(v); // ERROR
2612
- ///
2613
- /// // In fact, `v` is invalid according to basic type layout invariants, so *any*
2614
- /// // operation touching it is undefined behavior.
2615
- /// // let v2 = v; // ERROR
2616
- ///
2617
- /// unsafe {
2618
- /// // Let us instead put in a valid value
2619
- /// ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
2620
- /// }
2621
- ///
2622
- /// // Now the box is fine
2623
- /// assert_eq!(*v, 42);
2624
- /// ```
2625
2602
#[ doc( alias = "memset" ) ]
2626
2603
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2627
2604
#[ cfg_attr( not( bootstrap) , rustc_allowed_through_unstable_modules) ]
0 commit comments