]> git.proxmox.com Git - rustc.git/blame - src/doc/book/src/ch19-01-unsafe-rust.md
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / src / doc / book / src / ch19-01-unsafe-rust.md
CommitLineData
13cf67c4
XL
1## Unsafe Rust
2
3All the code we’ve discussed so far has had Rust’s memory safety guarantees
4enforced at compile time. However, Rust has a second language hidden inside it
5that doesn’t enforce these memory safety guarantees: it’s called *unsafe Rust*
6and works just like regular Rust, but gives us extra superpowers.
7
8Unsafe Rust exists because, by nature, static analysis is conservative. When
9the compiler tries to determine whether or not code upholds the guarantees,
10it’s better for it to reject some valid programs rather than accept some
11invalid programs. Although the code might be okay, as far as Rust is able to
12tell, it’s not! In these cases, you can use unsafe code to tell the compiler,
13“Trust me, I know what I’m doing.” The downside is that you use it at your own
14risk: if you use unsafe code incorrectly, problems due to memory unsafety, such
15as null pointer dereferencing, can occur.
16
17Another reason Rust has an unsafe alter ego is that the underlying computer
18hardware is inherently unsafe. If Rust didn’t let you do unsafe operations, you
19couldn’t do certain tasks. Rust needs to allow you to do low-level systems
20programming, such as directly interacting with the operating system or even
21writing your own operating system. Working with low-level systems programming
22is one of the goals of the language. Let’s explore what we can do with unsafe
23Rust and how to do it.
24
25### Unsafe Superpowers
26
27To switch to unsafe Rust, use the `unsafe` keyword and then start a new block
74b04a01 28that holds the unsafe code. You can take five actions in unsafe Rust, called
13cf67c4
XL
29*unsafe superpowers*, that you can’t in safe Rust. Those superpowers include
30the ability to:
31
32* Dereference a raw pointer
33* Call an unsafe function or method
34* Access or modify a mutable static variable
35* Implement an unsafe trait
e1599b0c 36* Access fields of `union`s
13cf67c4
XL
37
38It’s important to understand that `unsafe` doesn’t turn off the borrow checker
39or disable any other of Rust’s safety checks: if you use a reference in unsafe
40code, it will still be checked. The `unsafe` keyword only gives you access to
74b04a01 41these five features that are then not checked by the compiler for memory
13cf67c4
XL
42safety. You’ll still get some degree of safety inside of an unsafe block.
43
44In addition, `unsafe` does not mean the code inside the block is necessarily
45dangerous or that it will definitely have memory safety problems: the intent is
46that as the programmer, you’ll ensure the code inside an `unsafe` block will
47access memory in a valid way.
48
74b04a01 49People are fallible, and mistakes will happen, but by requiring these five
13cf67c4
XL
50unsafe operations to be inside blocks annotated with `unsafe` you’ll know that
51any errors related to memory safety must be within an `unsafe` block. Keep
52`unsafe` blocks small; you’ll be thankful later when you investigate memory
53bugs.
54
55To isolate unsafe code as much as possible, it’s best to enclose unsafe code
56within a safe abstraction and provide a safe API, which we’ll discuss later in
57the chapter when we examine unsafe functions and methods. Parts of the standard
58library are implemented as safe abstractions over unsafe code that has been
59audited. Wrapping unsafe code in a safe abstraction prevents uses of `unsafe`
60from leaking out into all the places that you or your users might want to use
61the functionality implemented with `unsafe` code, because using a safe
62abstraction is safe.
63
74b04a01 64Let’s look at each of the five unsafe superpowers in turn. We’ll also look at
13cf67c4
XL
65some abstractions that provide a safe interface to unsafe code.
66
67### Dereferencing a Raw Pointer
68
9fa01778
XL
69In Chapter 4, in the [“Dangling References”][dangling-references]<!-- ignore
70--> section, we mentioned that the compiler ensures references are always
71valid. Unsafe Rust has two new types called *raw pointers* that are similar to
72references. As with references, raw pointers can be immutable or mutable and
73are written as `*const T` and `*mut T`, respectively. The asterisk isn’t the
74dereference operator; it’s part of the type name. In the context of raw
75pointers, *immutable* means that the pointer can’t be directly assigned to
76after being dereferenced.
13cf67c4
XL
77
78Different from references and smart pointers, raw pointers:
79
80* Are allowed to ignore the borrowing rules by having both immutable and
81 mutable pointers or multiple mutable pointers to the same location
82* Aren’t guaranteed to point to valid memory
83* Are allowed to be null
84* Don’t implement any automatic cleanup
85
86By opting out of having Rust enforce these guarantees, you can give up
87guaranteed safety in exchange for greater performance or the ability to
88interface with another language or hardware where Rust’s guarantees don’t apply.
89
90Listing 19-1 shows how to create an immutable and a mutable raw pointer from
91references.
92
93```rust
74b04a01 94{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-01/src/main.rs:here}}
13cf67c4
XL
95```
96
97<span class="caption">Listing 19-1: Creating raw pointers from references</span>
98
99Notice that we don’t include the `unsafe` keyword in this code. We can create
100raw pointers in safe code; we just can’t dereference raw pointers outside an
101unsafe block, as you’ll see in a bit.
102
103We’ve created raw pointers by using `as` to cast an immutable and a mutable
104reference into their corresponding raw pointer types. Because we created them
105directly from references guaranteed to be valid, we know these particular raw
106pointers are valid, but we can’t make that assumption about just any raw
107pointer.
108
109Next, we’ll create a raw pointer whose validity we can’t be so certain of.
110Listing 19-2 shows how to create a raw pointer to an arbitrary location in
111memory. Trying to use arbitrary memory is undefined: there might be data at
112that address or there might not, the compiler might optimize the code so there
113is no memory access, or the program might error with a segmentation fault.
114Usually, there is no good reason to write code like this, but it is possible.
115
116```rust
74b04a01 117{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-02/src/main.rs:here}}
13cf67c4
XL
118```
119
120<span class="caption">Listing 19-2: Creating a raw pointer to an arbitrary
121memory address</span>
122
123Recall that we can create raw pointers in safe code, but we can’t *dereference*
124raw pointers and read the data being pointed to. In Listing 19-3, we use the
125dereference operator `*` on a raw pointer that requires an `unsafe` block.
126
127```rust,unsafe
74b04a01 128{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-03/src/main.rs:here}}
13cf67c4
XL
129```
130
131<span class="caption">Listing 19-3: Dereferencing raw pointers within an
132`unsafe` block</span>
133
134Creating a pointer does no harm; it’s only when we try to access the value that
135it points at that we might end up dealing with an invalid value.
136
137Note also that in Listing 19-1 and 19-3, we created `*const i32` and `*mut i32`
138raw pointers that both pointed to the same memory location, where `num` is
139stored. If we instead tried to create an immutable and a mutable reference to
140`num`, the code would not have compiled because Rust’s ownership rules don’t
141allow a mutable reference at the same time as any immutable references. With
142raw pointers, we can create a mutable pointer and an immutable pointer to the
143same location and change data through the mutable pointer, potentially creating
144a data race. Be careful!
145
146With all of these dangers, why would you ever use raw pointers? One major use
147case is when interfacing with C code, as you’ll see in the next section,
9fa01778
XL
148[“Calling an Unsafe Function or
149Method.”](#calling-an-unsafe-function-or-method)<!-- ignore --> Another case is
150when building up safe abstractions that the borrow checker doesn’t understand.
151We’ll introduce unsafe functions and then look at an example of a safe
152abstraction that uses unsafe code.
13cf67c4
XL
153
154### Calling an Unsafe Function or Method
155
156The second type of operation that requires an unsafe block is calls to unsafe
157functions. Unsafe functions and methods look exactly like regular functions and
158methods, but they have an extra `unsafe` before the rest of the definition. The
159`unsafe` keyword in this context indicates the function has requirements we
160need to uphold when we call this function, because Rust can’t guarantee we’ve
161met these requirements. By calling an unsafe function within an `unsafe` block,
162we’re saying that we’ve read this function’s documentation and take
163responsibility for upholding the function’s contracts.
164
165Here is an unsafe function named `dangerous` that doesn’t do anything in its
166body:
167
168```rust,unsafe
74b04a01 169{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-01-unsafe-fn/src/main.rs:here}}
13cf67c4
XL
170```
171
172We must call the `dangerous` function within a separate `unsafe` block. If we
173try to call `dangerous` without the `unsafe` block, we’ll get an error:
174
f035d41b 175```console
74b04a01 176{{#include ../listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt}}
13cf67c4
XL
177```
178
179By inserting the `unsafe` block around our call to `dangerous`, we’re asserting
180to Rust that we’ve read the function’s documentation, we understand how to use
181it properly, and we’ve verified that we’re fulfilling the contract of the
182function.
183
184Bodies of unsafe functions are effectively `unsafe` blocks, so to perform other
185unsafe operations within an unsafe function, we don’t need to add another
186`unsafe` block.
187
188#### Creating a Safe Abstraction over Unsafe Code
189
190Just because a function contains unsafe code doesn’t mean we need to mark the
191entire function as unsafe. In fact, wrapping unsafe code in a safe function is
192a common abstraction. As an example, let’s study a function from the standard
193library, `split_at_mut`, that requires some unsafe code and explore how we
194might implement it. This safe method is defined on mutable slices: it takes one
195slice and makes it two by splitting the slice at the index given as an
196argument. Listing 19-4 shows how to use `split_at_mut`.
197
198```rust
74b04a01 199{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-04/src/main.rs:here}}
13cf67c4
XL
200```
201
202<span class="caption">Listing 19-4: Using the safe `split_at_mut`
203function</span>
204
205We can’t implement this function using only safe Rust. An attempt might look
206something like Listing 19-5, which won’t compile. For simplicity, we’ll
207implement `split_at_mut` as a function rather than a method and only for slices
208of `i32` values rather than for a generic type `T`.
209
210```rust,ignore,does_not_compile
74b04a01 211{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-05/src/main.rs:here}}
13cf67c4
XL
212```
213
214<span class="caption">Listing 19-5: An attempted implementation of
215`split_at_mut` using only safe Rust</span>
216
217This function first gets the total length of the slice. Then it asserts that
218the index given as a parameter is within the slice by checking whether it’s
219less than or equal to the length. The assertion means that if we pass an index
e74abb32 220that is greater than the length to split the slice at, the function will panic
13cf67c4
XL
221before it attempts to use that index.
222
223Then we return two mutable slices in a tuple: one from the start of the
224original slice to the `mid` index and another from `mid` to the end of the
225slice.
226
227When we try to compile the code in Listing 19-5, we’ll get an error.
228
f035d41b 229```console
74b04a01 230{{#include ../listings/ch19-advanced-features/listing-19-05/output.txt}}
13cf67c4
XL
231```
232
233Rust’s borrow checker can’t understand that we’re borrowing different parts of
234the slice; it only knows that we’re borrowing from the same slice twice.
235Borrowing different parts of a slice is fundamentally okay because the two
236slices aren’t overlapping, but Rust isn’t smart enough to know this. When we
237know code is okay, but Rust doesn’t, it’s time to reach for unsafe code.
238
239Listing 19-6 shows how to use an `unsafe` block, a raw pointer, and some calls
240to unsafe functions to make the implementation of `split_at_mut` work.
241
242```rust,unsafe
74b04a01 243{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-06/src/main.rs:here}}
13cf67c4
XL
244```
245
246<span class="caption">Listing 19-6: Using unsafe code in the implementation of
247the `split_at_mut` function</span>
248
9fa01778
XL
249Recall from [“The Slice Type”][the-slice-type]<!-- ignore --> section in
250Chapter 4 that slices are a pointer to some data and the length of the slice.
251We use the `len` method to get the length of a slice and the `as_mut_ptr`
252method to access the raw pointer of a slice. In this case, because we have a
253mutable slice to `i32` values, `as_mut_ptr` returns a raw pointer with the type
254`*mut i32`, which we’ve stored in the variable `ptr`.
13cf67c4
XL
255
256We keep the assertion that the `mid` index is within the slice. Then we get to
257the unsafe code: the `slice::from_raw_parts_mut` function takes a raw pointer
258and a length, and it creates a slice. We use this function to create a slice
74b04a01 259that starts from `ptr` and is `mid` items long. Then we call the `add`
13cf67c4
XL
260method on `ptr` with `mid` as an argument to get a raw pointer that starts at
261`mid`, and we create a slice using that pointer and the remaining number of
262items after `mid` as the length.
263
264The function `slice::from_raw_parts_mut` is unsafe because it takes a raw
74b04a01 265pointer and must trust that this pointer is valid. The `add` method on raw
13cf67c4
XL
266pointers is also unsafe, because it must trust that the offset location is also
267a valid pointer. Therefore, we had to put an `unsafe` block around our calls to
74b04a01 268`slice::from_raw_parts_mut` and `add` so we could call them. By looking at
13cf67c4
XL
269the code and by adding the assertion that `mid` must be less than or equal to
270`len`, we can tell that all the raw pointers used within the `unsafe` block
271will be valid pointers to data within the slice. This is an acceptable and
272appropriate use of `unsafe`.
273
274Note that we don’t need to mark the resulting `split_at_mut` function as
275`unsafe`, and we can call this function from safe Rust. We’ve created a safe
276abstraction to the unsafe code with an implementation of the function that uses
277`unsafe` code in a safe way, because it creates only valid pointers from the
278data this function has access to.
279
280In contrast, the use of `slice::from_raw_parts_mut` in Listing 19-7 would
281likely crash when the slice is used. This code takes an arbitrary memory
282location and creates a slice 10,000 items long.
283
284```rust,unsafe
74b04a01 285{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-07/src/main.rs:here}}
13cf67c4
XL
286```
287
288<span class="caption">Listing 19-7: Creating a slice from an arbitrary memory
289location</span>
290
291We don’t own the memory at this arbitrary location, and there is no guarantee
292that the slice this code creates contains valid `i32` values. Attempting to use
9fa01778 293`slice` as though it’s a valid slice results in undefined behavior.
13cf67c4
XL
294
295#### Using `extern` Functions to Call External Code
296
297Sometimes, your Rust code might need to interact with code written in another
298language. For this, Rust has a keyword, `extern`, that facilitates the creation
299and use of a *Foreign Function Interface (FFI)*. An FFI is a way for a
300programming language to define functions and enable a different (foreign)
301programming language to call those functions.
302
303Listing 19-8 demonstrates how to set up an integration with the `abs` function
304from the C standard library. Functions declared within `extern` blocks are
305always unsafe to call from Rust code. The reason is that other languages don’t
306enforce Rust’s rules and guarantees, and Rust can’t check them, so
307responsibility falls on the programmer to ensure safety.
308
309<span class="filename">Filename: src/main.rs</span>
310
311```rust,unsafe
74b04a01 312{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-08/src/main.rs}}
13cf67c4
XL
313```
314
315<span class="caption">Listing 19-8: Declaring and calling an `extern` function
316defined in another language</span>
317
318Within the `extern "C"` block, we list the names and signatures of external
319functions from another language we want to call. The `"C"` part defines which
320*application binary interface (ABI)* the external function uses: the ABI
321defines how to call the function at the assembly level. The `"C"` ABI is the
322most common and follows the C programming language’s ABI.
323
324> #### Calling Rust Functions from Other Languages
325>
326> We can also use `extern` to create an interface that allows other languages
327> to call Rust functions. Instead of an `extern` block, we add the `extern`
328> keyword and specify the ABI to use just before the `fn` keyword. We also need
329> to add a `#[no_mangle]` annotation to tell the Rust compiler not to mangle
330> the name of this function. *Mangling* is when a compiler changes the name
331> we’ve given a function to a different name that contains more information for
332> other parts of the compilation process to consume but is less human readable.
333> Every programming language compiler mangles names slightly differently, so
334> for a Rust function to be nameable by other languages, we must disable the
335> Rust compiler’s name mangling.
336>
337> In the following example, we make the `call_from_c` function accessible from
338> C code, after it’s compiled to a shared library and linked from C:
339>
340> ```rust
341> #[no_mangle]
342> pub extern "C" fn call_from_c() {
343> println!("Just called a Rust function from C!");
344> }
345> ```
346>
347> This usage of `extern` does not require `unsafe`.
348
349### Accessing or Modifying a Mutable Static Variable
350
351Until now, we’ve not talked about *global variables*, which Rust does support
352but can be problematic with Rust’s ownership rules. If two threads are
353accessing the same mutable global variable, it can cause a data race.
354
355In Rust, global variables are called *static* variables. Listing 19-9 shows an
356example declaration and use of a static variable with a string slice as a
357value.
358
359<span class="filename">Filename: src/main.rs</span>
360
361```rust
74b04a01 362{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-09/src/main.rs}}
13cf67c4
XL
363```
364
365<span class="caption">Listing 19-9: Defining and using an immutable static
366variable</span>
367
368Static variables are similar to constants, which we discussed in the
dc9dc135
XL
369[“Differences Between Variables and
370Constants”][differences-between-variables-and-constants]<!-- ignore -->
371section in Chapter 3. The names of static variables are in
372`SCREAMING_SNAKE_CASE` by convention, and we *must* annotate the variable’s
373type, which is `&'static str` in this example. Static variables can only store
374references with the `'static` lifetime, which means the Rust compiler can
375figure out the lifetime; we don’t need to annotate it explicitly. Accessing an
376immutable static variable is safe.
13cf67c4
XL
377
378Constants and immutable static variables might seem similar, but a subtle
379difference is that values in a static variable have a fixed address in memory.
380Using the value will always access the same data. Constants, on the other hand,
381are allowed to duplicate their data whenever they’re used.
382
383Another difference between constants and static variables is that static
384variables can be mutable. Accessing and modifying mutable static variables is
385*unsafe*. Listing 19-10 shows how to declare, access, and modify a mutable
386static variable named `COUNTER`.
387
388<span class="filename">Filename: src/main.rs</span>
389
390```rust,unsafe
74b04a01 391{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-10/src/main.rs}}
13cf67c4
XL
392```
393
394<span class="caption">Listing 19-10: Reading from or writing to a mutable
395static variable is unsafe</span>
396
397As with regular variables, we specify mutability using the `mut` keyword. Any
398code that reads or writes from `COUNTER` must be within an `unsafe` block. This
399code compiles and prints `COUNTER: 3` as we would expect because it’s single
400threaded. Having multiple threads access `COUNTER` would likely result in data
401races.
402
403With mutable data that is globally accessible, it’s difficult to ensure there
404are no data races, which is why Rust considers mutable static variables to be
405unsafe. Where possible, it’s preferable to use the concurrency techniques and
406thread-safe smart pointers we discussed in Chapter 16 so the compiler checks
407that data accessed from different threads is done safely.
408
409### Implementing an Unsafe Trait
410
411The final action that works only with `unsafe` is implementing an unsafe trait.
412A trait is unsafe when at least one of its methods has some invariant that the
413compiler can’t verify. We can declare that a trait is `unsafe` by adding the
414`unsafe` keyword before `trait` and marking the implementation of the trait as
415`unsafe` too, as shown in Listing 19-11.
416
417```rust,unsafe
74b04a01 418{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-11/src/main.rs}}
13cf67c4
XL
419```
420
421<span class="caption">Listing 19-11: Defining and implementing an unsafe
422trait</span>
423
424By using `unsafe impl`, we’re promising that we’ll uphold the invariants that
425the compiler can’t verify.
426
427As an example, recall the `Sync` and `Send` marker traits we discussed in the
dc9dc135
XL
428[“Extensible Concurrency with the `Sync` and `Send`
429Traits”][extensible-concurrency-with-the-sync-and-send-traits]<!-- ignore -->
430section in Chapter 16: the compiler implements these traits automatically if
431our types are composed entirely of `Send` and `Sync` types. If we implement a
432type that contains a type that is not `Send` or `Sync`, such as raw pointers,
433and we want to mark that type as `Send` or `Sync`, we must use `unsafe`. Rust
434can’t verify that our type upholds the guarantees that it can be safely sent
435across threads or accessed from multiple threads; therefore, we need to do
436those checks manually and indicate as such with `unsafe`.
13cf67c4 437
74b04a01
XL
438### Accessing Fields of a Union
439
440A `union` is similar to a `struct`, but only one declared field is used in a
441particular instance at one time. Unions are primarily used to interface with
442unions in C code. Accessing union fields is unsafe because Rust can’t guarantee
443the type of the data currently being stored in the union instance. You can
444learn more about unions in [the reference][reference].
445
13cf67c4
XL
446### When to Use Unsafe Code
447
74b04a01 448Using `unsafe` to take one of the five actions (superpowers) just discussed
13cf67c4
XL
449isn’t wrong or even frowned upon. But it is trickier to get `unsafe` code
450correct because the compiler can’t help uphold memory safety. When you have a
451reason to use `unsafe` code, you can do so, and having the explicit `unsafe`
74b04a01 452annotation makes it easier to track down the source of problems when they occur.
9fa01778
XL
453
454[dangling-references]:
455ch04-02-references-and-borrowing.html#dangling-references
456[differences-between-variables-and-constants]:
457ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
458[extensible-concurrency-with-the-sync-and-send-traits]:
459ch16-04-extensible-concurrency-sync-and-send.html#extensible-concurrency-with-the-sync-and-send-traits
460[the-slice-type]: ch04-03-slices.html#the-slice-type
74b04a01 461[reference]: ../reference/items/unions.html