-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Rewrite docs for pointer methods #53783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
911d35f
da58beb
9f5a3cc
04a08c6
7b2ef6b
6f7338b
30122e9
e40585f
ea5570c
3a55c85
95a9088
7e165d9
c8da321
b0c5dc2
098bec8
fc63113
1ec66fb
e869b81
d97f61f
c06f551
2741224
18a7bdb
4ed469c
dc2237c
b463871
408a6a0
755de3c
bc809e0
78f5b68
c44e88c
2713d36
0ec87d0
adcc0d2
c197dc4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -962,59 +962,125 @@ extern "rust-intrinsic" { | |
/// value is not necessarily valid to be used to actually access memory. | ||
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T; | ||
|
||
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source | ||
/// and destination may *not* overlap. | ||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source | ||
/// and destination must *not* overlap. | ||
/// | ||
/// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. | ||
/// For regions of memory which might overlap, use [`copy`] instead. | ||
/// | ||
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`]. | ||
/// | ||
/// [`copy`]: ./fn.copy.html | ||
/// [`memcpy`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memcpy | ||
/// | ||
/// # Safety | ||
/// | ||
/// Beyond requiring that the program must be allowed to access both regions | ||
/// of memory, it is Undefined Behavior for source and destination to | ||
/// overlap. Care must also be taken with the ownership of `src` and | ||
/// `dst`. This method semantically moves the values of `src` into `dst`. | ||
/// However it does not drop the contents of `dst`, or prevent the contents | ||
/// of `src` from being dropped or used. | ||
/// Behavior is undefined if any of the following conditions are violated: | ||
/// | ||
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes. | ||
/// | ||
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes. | ||
/// | ||
/// * Both `src` and `dst` must be properly aligned. | ||
/// | ||
/// * The region of memory beginning at `src` with a size of `count * | ||
/// size_of::<T>()` bytes must *not* overlap with the region of memory | ||
/// beginning at `dst` with the same size. | ||
/// | ||
/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of | ||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values | ||
/// in the region beginning at `*src` and the region beginning at `*dst` can | ||
/// [violate memory safety][read-ownership]. | ||
/// | ||
/// These restrictions apply even if the effectively copied size (`count * | ||
/// size_of::<T>()`) is `0`. | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// [`Copy`]: ../marker/trait.Copy.html | ||
/// [`read`]: ../ptr/fn.read.html | ||
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value | ||
/// [valid]: ../ptr/index.html#safety | ||
/// | ||
/// # Examples | ||
/// | ||
/// A safe swap function: | ||
/// Manually implement [`Vec::append`]: | ||
/// | ||
/// ``` | ||
/// use std::mem; | ||
/// use std::ptr; | ||
/// | ||
/// # #[allow(dead_code)] | ||
/// fn swap<T>(x: &mut T, y: &mut T) { | ||
/// /// Moves all the elements of `src` into `dst`, leaving `src` empty. | ||
/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) { | ||
/// let src_len = src.len(); | ||
/// let dst_len = dst.len(); | ||
/// | ||
/// // Ensure that `dst` has enough capacity to hold all of `src`. | ||
/// dst.reserve(src_len); | ||
/// | ||
/// unsafe { | ||
/// // Give ourselves some scratch space to work with | ||
/// let mut t: T = mem::uninitialized(); | ||
/// // The call to offset is always safe because `Vec` will never | ||
/// // allocate more than `isize::MAX` bytes. | ||
/// let dst = dst.as_mut_ptr().offset(dst_len as isize); | ||
/// let src = src.as_ptr(); | ||
/// | ||
/// // The two regions cannot overlap becuase mutable references do | ||
/// // not alias, and two different vectors cannot own the same | ||
/// // memory. | ||
/// ptr::copy_nonoverlapping(src, dst, src_len); | ||
/// } | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// // Perform the swap, `&mut` pointers never alias | ||
/// ptr::copy_nonoverlapping(x, &mut t, 1); | ||
/// ptr::copy_nonoverlapping(y, x, 1); | ||
/// ptr::copy_nonoverlapping(&t, y, 1); | ||
/// unsafe { | ||
/// // Truncate `src` without dropping its contents. | ||
/// src.set_len(0); | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// // y and t now point to the same thing, but we need to completely forget `t` | ||
/// // because it's no longer relevant. | ||
/// mem::forget(t); | ||
/// // Notify `dst` that it now holds the contents of `src`. | ||
/// dst.set_len(dst_len + src_len); | ||
/// } | ||
/// } | ||
/// | ||
/// let mut a = vec!['r']; | ||
/// let mut b = vec!['u', 's', 't']; | ||
/// | ||
/// append(&mut a, &mut b); | ||
/// | ||
/// assert_eq!(a, &['r', 'u', 's', 't']); | ||
/// assert!(b.is_empty()); | ||
/// ``` | ||
/// | ||
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); | ||
|
||
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source | ||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source | ||
/// and destination may overlap. | ||
/// | ||
/// `copy` is semantically equivalent to C's `memmove`. | ||
/// If the source and destination will *never* overlap, | ||
/// [`copy_nonoverlapping`] can be used instead. | ||
/// | ||
/// `copy` is semantically equivalent to C's [`memmove`]. | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html | ||
/// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// # Safety | ||
/// | ||
/// Care must be taken with the ownership of `src` and `dst`. | ||
/// This method semantically moves the values of `src` into `dst`. | ||
/// However it does not drop the contents of `dst`, or prevent the contents of `src` | ||
/// from being dropped or used. | ||
/// Behavior is undefined if any of the following conditions are violated: | ||
/// | ||
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes. | ||
/// | ||
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes. | ||
/// | ||
/// * Both `src` and `dst` must be properly aligned. | ||
/// | ||
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of | ||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values | ||
/// in the region beginning at `*src` and the region beginning at `*dst` can | ||
/// [violate memory safety][read-ownership]. | ||
/// | ||
/// These restrictions apply even if the effectively copied size (`count * | ||
/// size_of::<T>()`) is `0`. | ||
/// | ||
/// [`Copy`]: ../marker/trait.Copy.html | ||
/// [`read`]: ../ptr/fn.read.html | ||
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value | ||
/// [valid]: ../ptr/index.html#safety | ||
/// | ||
/// # Examples | ||
/// | ||
|
@@ -1031,24 +1097,65 @@ extern "rust-intrinsic" { | |
/// dst | ||
/// } | ||
/// ``` | ||
/// | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize); | ||
|
||
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()` | ||
/// bytes of memory starting at `dst` to `val`. | ||
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to | ||
/// `val`. | ||
/// | ||
/// `write_bytes` is similar to C's [`memset`], but sets `count * | ||
/// size_of::<T>()` bytes to `val`. | ||
/// | ||
/// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// # Safety | ||
/// | ||
/// Behavior is undefined if any of the following conditions are violated: | ||
/// | ||
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes. | ||
/// | ||
/// * `dst` must be properly aligned. | ||
/// | ||
/// Additionally, the caller must ensure that writing `count * | ||
/// size_of::<T>()` bytes to the given region of memory results in a valid | ||
/// value of `T`. Creating an invalid value of `T` can result in undefined | ||
/// behavior. | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// These restrictions apply even if the effectively written size (`count * | ||
/// size_of::<T>()`) is `0`. | ||
/// | ||
/// [valid]: ../ptr/index.html#safety | ||
/// | ||
/// # Examples | ||
/// | ||
/// Basic usage: | ||
/// | ||
/// ``` | ||
/// use std::ptr; | ||
/// | ||
/// let mut vec = vec![0; 4]; | ||
/// let mut vec = vec![0u32; 4]; | ||
/// unsafe { | ||
/// let vec_ptr = vec.as_mut_ptr(); | ||
/// ptr::write_bytes(vec_ptr, b'a', 2); | ||
/// ptr::write_bytes(vec_ptr, 0xfe, 2); | ||
/// } | ||
/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]); | ||
/// ``` | ||
/// | ||
/// Creating an invalid value: | ||
/// | ||
/// ```no_run | ||
/// use std::ptr; | ||
/// | ||
/// let mut v = Box::new(0i32); | ||
/// | ||
/// unsafe { | ||
/// // Leaks the previously held value by overwriting the `Box<T>` with | ||
/// // a null pointer. | ||
/// ptr::write_bytes(&mut v, 0, 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not entirely sure what's going on here? Is it overwriting the pointer inside the Making this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My intention here was to demonstrate that creating an invalid value can result in UB later in the program, outside of the Rereading it now, it does seem a bit convoluted. Perhaps we could write an arbitrary value (instead of 0), or-- since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the |
||
/// } | ||
/// assert_eq!(vec, [b'a', b'a', 0, 0]); | ||
/// | ||
/// // At this point, using or dropping `v` results in undefined behavior. | ||
/// // v = Box::new(0i32); // ERROR | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// ``` | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize); | ||
|
@@ -1066,7 +1173,7 @@ extern "rust-intrinsic" { | |
/// `min_align_of::<T>()` | ||
/// | ||
/// The volatile parameter is set to `true`, so it will not be optimized out | ||
/// unless size is equal to zero.. | ||
/// unless size is equal to zero. | ||
pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize); | ||
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a | ||
/// size of `count` * `size_of::<T>()` and an alignment of | ||
|
Uh oh!
There was an error while loading. Please reload this page.