@@ -303,6 +303,9 @@ impl<T: ?Sized> *const T {
303303 /// byte past the end of the same allocated object. Note that in Rust,
304304 /// every (stack-allocated) variable is considered a separate allocated object.
305305 ///
306+ /// * Both pointers must be *derived from* a pointer to the same object.
307+ /// (See below for an example.)
308+ ///
306309 /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
307310 ///
308311 /// * The distance between the pointers, in bytes, must be an exact multiple
@@ -348,6 +351,25 @@ impl<T: ?Sized> *const T {
348351 /// assert_eq!(ptr2.offset(-2), ptr1);
349352 /// }
350353 /// ```
354+ ///
355+ /// *Incorrect* usage:
356+ ///
357+ /// ```rust,no_run
358+ /// #![feature(ptr_offset_from)]
359+ ///
360+ /// let ptr1 = Box::into_raw(Box::new(0u8)) as *const u8;
361+ /// let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
362+ /// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
363+ /// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
364+ /// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff);
365+ /// assert_eq!(ptr2 as usize, ptr2_other as usize);
366+ /// // Since ptr2_other and ptr2 are derived from pointers to different objects,
367+ /// // computing their offset is undefined behavior, even though
368+ /// // they point to the same address!
369+ /// unsafe {
370+ /// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
371+ /// }
372+ /// ```
351373 #[ unstable( feature = "ptr_offset_from" , issue = "41079" ) ]
352374 #[ rustc_const_unstable( feature = "const_ptr_offset_from" , issue = "41079" ) ]
353375 #[ inline]
0 commit comments