]>
Commit | Line | Data |
---|---|---|
2c00a5a8 XL |
1 | # Unsafe Operations |
2 | ||
3 | As an introduction to this section, to borrow from [the official docs][unsafe], | |
4 | "one should try to minimize the amount of unsafe code in a code base." With that | |
0bf4aa26 XL |
5 | in mind, let's get started! Unsafe annotations in Rust are used to bypass |
6 | protections put in place by the compiler; specifically, there are four primary | |
7 | things that unsafe is used for: | |
2c00a5a8 XL |
8 | |
9 | * dereferencing raw pointers | |
0bf4aa26 | 10 | * calling functions or methods which are `unsafe` (including calling a function |
dc9dc135 | 11 | over FFI, see [a previous chapter](std_misc/ffi.md) of the book) |
0bf4aa26 XL |
12 | * accessing or modifying static mutable variables |
13 | * implementing unsafe traits | |
2c00a5a8 XL |
14 | |
15 | ### Raw Pointers | |
16 | Raw pointers `*` and references `&T` function similarly, but references are | |
17 | always safe because they are guaranteed to point to valid data due to the | |
18 | borrow checker. Dereferencing a raw pointer can only be done through an unsafe | |
19 | block. | |
20 | ||
21 | ```rust,editable | |
22 | fn main() { | |
23 | let raw_p: *const u32 = &10; | |
24 | ||
25 | unsafe { | |
26 | assert!(*raw_p == 10); | |
27 | } | |
28 | } | |
29 | ``` | |
30 | ||
31 | ### Calling Unsafe Functions | |
32 | Some functions can be declared as `unsafe`, meaning it is the programmer's | |
33 | responsibility to ensure correctness instead of the compiler's. One example | |
34 | of this is [`std::slice::from_raw_parts`] which will create a slice given a | |
35 | pointer to the first element and a length. | |
36 | ||
37 | ```rust,editable | |
38 | use std::slice; | |
39 | ||
40 | fn main() { | |
41 | let some_vector = vec![1, 2, 3, 4]; | |
42 | ||
43 | let pointer = some_vector.as_ptr(); | |
44 | let length = some_vector.len(); | |
45 | ||
46 | unsafe { | |
47 | let my_slice: &[u32] = slice::from_raw_parts(pointer, length); | |
0bf4aa26 | 48 | |
2c00a5a8 XL |
49 | assert_eq!(some_vector.as_slice(), my_slice); |
50 | } | |
51 | } | |
52 | ``` | |
53 | ||
54 | For `slice::from_raw_parts`, one of the assumptions which *must* be upheld is | |
55 | that the pointer passed in points to valid memory and that the memory pointed to | |
56 | is of the correct type. If these invariants aren't upheld then the program's | |
57 | behaviour is undefined and there is no knowing what will happen. | |
58 | ||
59 | ||
532ac7d7 | 60 | [unsafe]: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html |
2c00a5a8 | 61 | [`std::slice::from_raw_parts`]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html |