Skip to content

Commit 7e165d9

Browse files
ecstatic-morseRalfJung
authored andcommitted
Add a list of known facts re: validity
Also rewrites the reads/writes section to be less reliant on `*const`, `*mut`
1 parent 95a9088 commit 7e165d9

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

src/libcore/ptr.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,37 @@
2121
//! rust does not yet have a formal memory model, determining whether an
2222
//! arbitrary pointer is valid for a given operation can be tricky.
2323
//!
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.
3031
//!
31-
//! Additionally, some functions (e.g. [`copy`]) take a single pointer but
32+
//! Some functions (e.g. [`copy`]) take a single pointer but
3233
//! operate on many values. In this case, the function will state the size of
3334
//! the operation for which the pointer must be valid. For example,
3435
//! `copy::<T>(&src, &mut dst, 3)` requires `dst` to be valid for writes of
3536
//! `size_of::<T>() * 3` bytes. When the documentation requires that a pointer
3637
//! be valid for an operation but omits the size of that operation, the size is
3738
//! implied to be `size_of::<T>()` bytes.
3839
//!
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
4155
//! to [undefined behavior][ub].
4256
//!
4357
//! ## Alignment
@@ -50,7 +64,10 @@
5064
//! [aliasing]: ../../nomicon/aliasing.html
5165
//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
5266
//! [ub]: ../../reference/behavior-considered-undefined.html
67+
//! [null]: ./fn.null.html
68+
//! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts
5369
//! [`copy`]: ../../std/ptr/fn.copy.html
70+
//! [`offset`]: ../../std/primitive.pointer.html#method.offset
5471
//! [`read_unaligned`]: ./fn.read_unaligned.html
5572
//! [`write_unaligned`]: ./fn.write_unaligned.html
5673

0 commit comments

Comments
 (0)