|
21 | 21 | //! rust does not yet have a formal memory model, determining whether an
|
22 | 22 | //! arbitrary pointer is valid for a given operation can be tricky.
|
23 | 23 | //!
|
24 |
| -//! There are two types of operations on memory, reads and writes. It is |
25 |
| -//! possible for a `*mut` to be valid for one operation and not the other. Since |
26 |
| -//! a `*const` can only be read and not written, it has no such ambiguity. For |
27 |
| -//! example, a `*mut` is not valid for writes if a a reference exists which |
28 |
| -//! [refers to the same memory][aliasing]. Therefore, each function in this |
29 |
| -//! module will document which operations must be valid on any `*mut` arguments. |
| 24 | +//! There are two types of operations on memory, reads and writes. A single |
| 25 | +//! pointer can be valid for any combination of these operations. For example, a |
| 26 | +//! pointer is not valid for writes if a `&mut` exists which [refers to the same |
| 27 | +//! memory][aliasing]. The set of operations for which a pointer argument must |
| 28 | +//! be valid is explicitly documented for each function. This is not strictly |
| 29 | +//! necessary for `*const` arguments, as they can only be used for reads and |
| 30 | +//! never for writes. |
30 | 31 | //!
|
31 |
| -//! Additionally, some functions (e.g. [`copy`]) take a single pointer but |
| 32 | +//! Some functions (e.g. [`copy`]) take a single pointer but |
32 | 33 | //! operate on many values. In this case, the function will state the size of
|
33 | 34 | //! the operation for which the pointer must be valid. For example,
|
34 | 35 | //! `copy::<T>(&src, &mut dst, 3)` requires `dst` to be valid for writes of
|
35 | 36 | //! `size_of::<T>() * 3` bytes. When the documentation requires that a pointer
|
36 | 37 | //! be valid for an operation but omits the size of that operation, the size is
|
37 | 38 | //! implied to be `size_of::<T>()` bytes.
|
38 | 39 | //!
|
39 |
| -//! For more information on the safety implications of dereferencing raw |
40 |
| -//! pointers, see the both the [book] and the section in the reference devoted |
| 40 | +//! While we can't yet define whether an arbitrary pointer is a valid one, there |
| 41 | +//! are a few rules regarding validity: |
| 42 | +//! |
| 43 | +//! * The result of casting a reference to a pointer is valid for as long as the |
| 44 | +//! underlying object is live. |
| 45 | +//! * All pointers to types with a [size of zero][zst] are valid for all |
| 46 | +//! operations of size zero. |
| 47 | +//! * A [null] pointer is *never* valid, except when it points to a zero-sized |
| 48 | +//! type. |
| 49 | +//! |
| 50 | +//! These axioms, along with careful use of [`offset`] for pointer arithmentic, |
| 51 | +//! are enough to correctly implement many useful things in unsafe code. Still, |
| 52 | +//! unsafe code should be carefully examined since some of the finer |
| 53 | +//! details—notably the [aliasing] rules—are not yet settled. For more |
| 54 | +//! information, see the [book] as well as the section in the reference devoted |
41 | 55 | //! to [undefined behavior][ub].
|
42 | 56 | //!
|
43 | 57 | //! ## Alignment
|
|
50 | 64 | //! [aliasing]: ../../nomicon/aliasing.html
|
51 | 65 | //! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
|
52 | 66 | //! [ub]: ../../reference/behavior-considered-undefined.html
|
| 67 | +//! [null]: ./fn.null.html |
| 68 | +//! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts |
53 | 69 | //! [`copy`]: ../../std/ptr/fn.copy.html
|
| 70 | +//! [`offset`]: ../../std/primitive.pointer.html#method.offset |
54 | 71 | //! [`read_unaligned`]: ./fn.read_unaligned.html
|
55 | 72 | //! [`write_unaligned`]: ./fn.write_unaligned.html
|
56 | 73 |
|
|
0 commit comments