edit docs a little
This commit is contained in:
parent
c8da321581
commit
b0c5dc2cc1
@ -986,11 +986,14 @@
|
||||
/// size_of::<T>()` bytes must *not* overlap with the region of memory
|
||||
/// beginning at `dst` with the same size.
|
||||
///
|
||||
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
|
||||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
|
||||
/// 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`.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`read`]: ../ptr/fn.read.html
|
||||
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
|
||||
@ -1071,6 +1074,9 @@
|
||||
/// 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
|
||||
@ -1115,6 +1121,9 @@
|
||||
/// value of `T`. Creating an invalid value of `T` can result in undefined
|
||||
/// behavior.
|
||||
///
|
||||
/// These restrictions apply even if the effectively written size (`count *
|
||||
/// size_of::<T>()`) is `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
///
|
||||
/// # Examples
|
||||
@ -1164,7 +1173,7 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
|
||||
/// `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
|
||||
|
@ -16,35 +16,23 @@
|
||||
//!
|
||||
//! # Safety
|
||||
//!
|
||||
//! Many functions in this module take raw pointers as arguments and dereference
|
||||
//! them. For this to be safe, these pointers must be valid. However, because
|
||||
//! rust does not yet have a formal memory model, determining whether an
|
||||
//! arbitrary pointer is valid for a given operation can be tricky.
|
||||
//! Many functions in this module take raw pointers as arguments and read from
|
||||
//! or write to them. For this to be safe, these pointers must be *valid*.
|
||||
//! Whether a pointer is valid depends on the operation it is used for
|
||||
//! (read or write), and the extent of the memory that is accessed (i.e.,
|
||||
//! how many bytes are read/written). Most functions use `*mut T` and `*const T`
|
||||
//! to access only a single value, in which case the documentation omits the size
|
||||
//! and implicitly assumes it to be `size_of::<T>()` bytes.
|
||||
//!
|
||||
//! There are two types of operations on memory, reads and writes. A single
|
||||
//! pointer can be valid for any combination of these operations. For example, a
|
||||
//! pointer is not valid for writes if a `&mut` exists which [refers to the same
|
||||
//! memory][aliasing]. The set of operations for which a pointer argument must
|
||||
//! be valid is explicitly documented for each function. This is not strictly
|
||||
//! necessary for `*const` arguments, as they can only be used for reads and
|
||||
//! never for writes.
|
||||
//!
|
||||
//! Some functions (e.g. [`copy`]) take a single pointer but
|
||||
//! operate on many values. In this case, the function will state the size of
|
||||
//! the operation for which the pointer must be valid. For example,
|
||||
//! `copy::<T>(&src, &mut dst, 3)` requires `dst` to be valid for writes of
|
||||
//! `size_of::<T>() * 3` bytes. When the documentation requires that a pointer
|
||||
//! be valid for an operation but omits the size of that operation, the size is
|
||||
//! implied to be `size_of::<T>()` bytes.
|
||||
//!
|
||||
//! While we can't yet define whether an arbitrary pointer is a valid one, there
|
||||
//! While we can't yet define whether an arbitrary pointer is valid, there
|
||||
//! are a few rules regarding validity:
|
||||
//!
|
||||
//! * The result of casting a reference to a pointer is valid for as long as the
|
||||
//! underlying object is live.
|
||||
//! * A [null] pointer is *never* valid.
|
||||
//! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
|
||||
//! * All pointers (except for the null pointer) are valid for all operations of
|
||||
//! [size zero][zst].
|
||||
//! * The result of casting a reference to a pointer is valid for as long as the
|
||||
//! underlying object is live and no reference (just raw pointers) is used to
|
||||
//! access the same memory.
|
||||
//!
|
||||
//! These axioms, along with careful use of [`offset`] for pointer arithmentic,
|
||||
//! are enough to correctly implement many useful things in unsafe code. Still,
|
||||
@ -60,6 +48,10 @@
|
||||
//! this requirement in their documentation. Notable exceptions to this are
|
||||
//! [`read_unaligned`] and [`write_unaligned`].
|
||||
//!
|
||||
//! When a function requires proper alignment, it does so even if the access
|
||||
//! has size 0, i.e., even if memory is not actually touched. Consider using
|
||||
//! [`NonNull::dangling`] in such cases.
|
||||
//!
|
||||
//! [aliasing]: ../../nomicon/aliasing.html
|
||||
//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
|
||||
//! [ub]: ../../reference/behavior-considered-undefined.html
|
||||
@ -69,6 +61,7 @@
|
||||
//! [`offset`]: ../../std/primitive.pointer.html#method.offset
|
||||
//! [`read_unaligned`]: ./fn.read_unaligned.html
|
||||
//! [`write_unaligned`]: ./fn.write_unaligned.html
|
||||
//! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
@ -122,6 +115,8 @@
|
||||
/// again. [`write`] can be used to overwrite data without causing it to be
|
||||
/// dropped.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`write`]: ../ptr/fn.write.html
|
||||
@ -211,6 +206,8 @@ pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
|
||||
///
|
||||
/// * Both `x` and `y` must be properly aligned.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
///
|
||||
/// # Examples
|
||||
@ -278,6 +275,8 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
||||
/// size_of::<T>()` bytes must *not* overlap with the region of memory
|
||||
/// beginning at `y` with the same size.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
///
|
||||
/// # Examples
|
||||
@ -389,6 +388,8 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
|
||||
///
|
||||
/// * `dest` must be properly aligned.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
///
|
||||
/// # Examples
|
||||
@ -426,6 +427,8 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
/// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the
|
||||
/// case.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// ## Ownership of the Returned Value
|
||||
///
|
||||
/// `read` creates a bitwise copy of `T`, regardless of whether `T` is [`Copy`].
|
||||
@ -540,6 +543,8 @@ pub unsafe fn read<T>(src: *const T) -> T {
|
||||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
|
||||
/// value and the value at `*src` can [violate memory safety][read-ownership].
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`read`]: ./fn.read.html
|
||||
/// [`write_unaligned`]: ./fn.write_unaligned.html
|
||||
@ -616,6 +621,8 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||
/// * `dst` must be properly aligned. Use [`write_unaligned`] if this is not the
|
||||
/// case.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
/// [`write_unaligned`]: ./fn.write_unaligned.html
|
||||
///
|
||||
@ -687,6 +694,8 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
|
||||
///
|
||||
/// * `dst` must be [valid] for writes.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
///
|
||||
/// # Examples
|
||||
@ -770,6 +779,8 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
||||
/// However, storing non-[`Copy`] types in volatile memory is almost certainly
|
||||
/// incorrect.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`read`]: ./fn.read.html
|
||||
@ -839,6 +850,8 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
||||
///
|
||||
/// * `dst` must be properly aligned.
|
||||
///
|
||||
/// These restrictions apply even if `T` has size `0`.
|
||||
///
|
||||
/// [valid]: ../ptr/index.html#safety
|
||||
///
|
||||
/// Just like in C, whether an operation is volatile has no bearing whatsoever
|
||||
|
Loading…
Reference in New Issue
Block a user