3
3
# Introduction
4
4
5
5
Rust aims to provide safe abstractions over the low-level details of
6
- the CPU and operating system, but sometimes one is forced to drop down
7
- and write code at that level (those abstractions have to be created
8
- somehow). This guide aims to provide an overview of the dangers and
9
- power one gets with Rust's unsafe subset.
6
+ the CPU and operating system, but sometimes one needs to drop down and
7
+ write code at that level. This guide aims to provide an overview of
8
+ the dangers and power one gets with Rust's unsafe subset.
10
9
11
10
Rust provides an escape hatch in the form of the ` unsafe { ... } `
12
- block which allows the programmer to dodge some of the compilers
11
+ block which allows the programmer to dodge some of the compiler's
13
12
checks and do a wide range of operations, such as:
14
13
15
14
- dereferencing [ raw pointers] ( #raw-pointers )
@@ -18,13 +17,12 @@ checks and do a wide range of operations, such as:
18
17
- [ inline assembly] ( #inline-assembly )
19
18
20
19
Note that an ` unsafe ` block does not relax the rules about lifetimes
21
- of ` & ` and the freezing of borrowed data, it just allows the use of
22
- additional techniques for skirting the compiler's watchful eye. Any
23
- use of ` unsafe ` is the programmer saying "I know more than you" to the
24
- compiler, and, as such, the programmer should be very sure that they
25
- actually do know more about why that piece of code is valid.
20
+ of ` & ` and the freezing of borrowed data.
26
21
27
- In general, one should try to minimize the amount of unsafe code in a
22
+ Any use of ` unsafe ` is the programmer saying "I know more than you" to
23
+ the compiler, and, as such, the programmer should be very sure that
24
+ they actually do know more about why that piece of code is valid. In
25
+ general, one should try to minimize the amount of unsafe code in a
28
26
code base; preferably by using the bare minimum ` unsafe ` blocks to
29
27
build safe interfaces.
30
28
@@ -38,25 +36,25 @@ build safe interfaces.
38
36
39
37
## References
40
38
41
- One of Rust's biggest goals as a language is ensuring memory safety,
42
- achieved in part via [ the lifetime system] ( guide-lifetimes.html ) which
43
- every ` & ` references has associated with it. This system is how the
39
+ One of Rust's biggest features is memory safety. This is achieved in
40
+ part via [ the lifetime system] ( guide-lifetimes.html ) , which is how the
44
41
compiler can guarantee that every ` & ` reference is always valid, and,
45
42
for example, never pointing to freed memory.
46
43
47
- These restrictions on ` & ` have huge advantages. However, there's no
48
- free lunch club. For example, ` & ` isn't a valid replacement for C's
49
- pointers, and so cannot be used for FFI, in general. Additionally,
50
- both immutable (` & ` ) and mutable (` &mut ` ) references have some
51
- aliasing and freezing guarantees, required for memory safety.
44
+ These restrictions on ` & ` have huge advantages. However, they also
45
+ constrain how we can use them. For example, ` & ` doesn't behave
46
+ identically to C's pointers, and so cannot be used for pointers in
47
+ foreign function interfaces (FFI). Additionally, both immutable (` & ` )
48
+ and mutable (` &mut ` ) references have some aliasing and freezing
49
+ guarantees, required for memory safety.
52
50
53
51
In particular, if you have an ` &T ` reference, then the ` T ` must not be
54
52
modified through that reference or any other reference. There are some
55
53
standard library types, e.g. ` Cell ` and ` RefCell ` , that provide inner
56
54
mutability by replacing compile time guarantees with dynamic checks at
57
55
runtime.
58
56
59
- An ` &mut ` reference has a stronger requirement : when an object has an
57
+ An ` &mut ` reference has a different constraint : when an object has an
60
58
` &mut T ` pointing into it, then that ` &mut ` reference must be the only
61
59
such usable path to that object in the whole program. That is, an
62
60
` &mut ` cannot alias with any other references.
@@ -106,19 +104,19 @@ offered by the Rust language and libraries. For example, they
106
104
107
105
Fortunately, they come with a redeeming feature: the weaker guarantees
108
106
mean weaker restrictions. The missing restrictions make raw pointers
109
- appropriate as a building block for (carefully!) implementing things
110
- like smart pointers and vectors inside libraries. For example, ` * `
111
- pointers are allowed to alias, allowing them to be used to write
112
- shared-ownership types like reference counted and garbage collected
113
- pointers, and even thread-safe shared memory types (` Rc ` and the ` Arc `
114
- types are both implemented entirely in Rust).
107
+ appropriate as a building block for implementing things like smart
108
+ pointers and vectors inside libraries. For example, ` * ` pointers are
109
+ allowed to alias, allowing them to be used to write shared-ownership
110
+ types like reference counted and garbage collected pointers, and even
111
+ thread-safe shared memory types (` Rc ` and the ` Arc ` types are both
112
+ implemented entirely in Rust).
115
113
116
114
There are two things that you are required to be careful about
117
115
(i.e. require an ` unsafe { ... } ` block) with raw pointers:
118
116
119
117
- dereferencing: they can have any value: so possible results include
120
118
a crash, a read of uninitialised memory, a use-after-free, or
121
- reading data as normal (and one hopes happens) .
119
+ reading data as normal.
122
120
- pointer arithmetic via the ` offset ` [ intrinsic] ( #intrinsics ) (or
123
121
` .offset ` method): this intrinsic uses so-called "in-bounds"
124
122
arithmetic, that is, it is only defined behaviour if the result is
@@ -177,9 +175,10 @@ code:
177
175
- store pointers privately (i.e. not in public fields of public
178
176
structs), so that you can see and control all reads and writes to
179
177
the pointer in one place.
180
- - use ` assert!() ` a lot: once you've thrown away the protection of the
181
- compiler & type-system via ` unsafe { ... } ` you're left with just
182
- your wits and your ` assert!() ` s, any bug is potentially exploitable.
178
+ - use ` assert!() ` a lot: since you can't rely on the protection of the
179
+ compiler & type-system to ensure that your ` unsafe ` code is correct
180
+ at compile-time, use ` assert!() ` to verify that it is doing the
181
+ right thing at run-time.
183
182
- implement the ` Drop ` for resource clean-up via a destructor, and use
184
183
RAII (Resource Acquisition Is Initialization). This reduces the need
185
184
for any manual memory management by users, and automatically ensures
@@ -298,8 +297,8 @@ asm!(assembly template
298
297
Any use of ` asm ` is feature gated (requires ` #![feature(asm)] ` on the
299
298
crate to allow) and of course requires an ` unsafe ` block.
300
299
301
- > ** Note** : the examples here are given in x86/x86-64 assembly, but all
302
- > platforms are supported.
300
+ > ** Note** : the examples here are given in x86/x86-64 assembly, but
301
+ > all platforms are supported.
303
302
304
303
## Assembly template
305
304
@@ -497,7 +496,7 @@ detects that it will overflow its stack. The example above uses the
497
496
> parts of the language may never be full specified and so details may
498
497
> differ wildly between implementations (and even versions of ` rustc `
499
498
> itself).
500
- >
499
+ >
501
500
> Furthermore, this is just an overview; the best form of
502
501
> documentation for specific instances of these features are their
503
502
> definitions and uses in ` std ` .
@@ -584,8 +583,7 @@ fn main(_argc: int, _argv: **u8) -> int {
584
583
```
585
584
586
585
Note the use of ` abort ` : the ` exchange_malloc ` lang item is assumed to
587
- return a valid pointer, and so needs to do the check
588
- internally.
586
+ return a valid pointer, and so needs to do the check internally.
589
587
590
588
Other features provided by lang items include:
591
589
0 commit comments