@@ -2566,14 +2566,23 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
25662566///
25672567/// * `dst` must be properly aligned.
25682568///
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- ///
25742569/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
25752570/// `0`, the pointer must be non-null and properly aligned.
25762571///
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+ ///
25772586/// [valid]: crate::ptr#safety
25782587///
25792588/// # Examples
@@ -2590,38 +2599,6 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
25902599/// }
25912600/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
25922601/// ```
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- /// ```
26252602#[ doc( alias = "memset" ) ]
26262603#[ stable( feature = "rust1" , since = "1.0.0" ) ]
26272604#[ cfg_attr( not( bootstrap) , rustc_allowed_through_unstable_modules) ]
0 commit comments