]>
Commit | Line | Data |
---|---|---|
13cf67c4 XL |
1 | ## Unsafe Rust |
2 | ||
3 | All the code we’ve discussed so far has had Rust’s memory safety guarantees | |
4 | enforced at compile time. However, Rust has a second language hidden inside it | |
5 | that doesn’t enforce these memory safety guarantees: it’s called *unsafe Rust* | |
6 | and works just like regular Rust, but gives us extra superpowers. | |
7 | ||
8 | Unsafe Rust exists because, by nature, static analysis is conservative. When | |
9 | the compiler tries to determine whether or not code upholds the guarantees, | |
10 | it’s better for it to reject some valid programs rather than accept some | |
11 | invalid programs. Although the code might be okay, as far as Rust is able to | |
12 | tell, 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 | |
14 | risk: if you use unsafe code incorrectly, problems due to memory unsafety, such | |
15 | as null pointer dereferencing, can occur. | |
16 | ||
17 | Another reason Rust has an unsafe alter ego is that the underlying computer | |
18 | hardware is inherently unsafe. If Rust didn’t let you do unsafe operations, you | |
19 | couldn’t do certain tasks. Rust needs to allow you to do low-level systems | |
20 | programming, such as directly interacting with the operating system or even | |
21 | writing your own operating system. Working with low-level systems programming | |
22 | is one of the goals of the language. Let’s explore what we can do with unsafe | |
23 | Rust and how to do it. | |
24 | ||
25 | ### Unsafe Superpowers | |
26 | ||
27 | To switch to unsafe Rust, use the `unsafe` keyword and then start a new block | |
74b04a01 | 28 | that 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 |
30 | the 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 | |
38 | It’s important to understand that `unsafe` doesn’t turn off the borrow checker | |
39 | or disable any other of Rust’s safety checks: if you use a reference in unsafe | |
40 | code, it will still be checked. The `unsafe` keyword only gives you access to | |
74b04a01 | 41 | these five features that are then not checked by the compiler for memory |
13cf67c4 XL |
42 | safety. You’ll still get some degree of safety inside of an unsafe block. |
43 | ||
44 | In addition, `unsafe` does not mean the code inside the block is necessarily | |
45 | dangerous or that it will definitely have memory safety problems: the intent is | |
46 | that as the programmer, you’ll ensure the code inside an `unsafe` block will | |
47 | access memory in a valid way. | |
48 | ||
74b04a01 | 49 | People are fallible, and mistakes will happen, but by requiring these five |
13cf67c4 XL |
50 | unsafe operations to be inside blocks annotated with `unsafe` you’ll know that |
51 | any 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 | |
53 | bugs. | |
54 | ||
55 | To isolate unsafe code as much as possible, it’s best to enclose unsafe code | |
56 | within a safe abstraction and provide a safe API, which we’ll discuss later in | |
57 | the chapter when we examine unsafe functions and methods. Parts of the standard | |
58 | library are implemented as safe abstractions over unsafe code that has been | |
59 | audited. Wrapping unsafe code in a safe abstraction prevents uses of `unsafe` | |
60 | from leaking out into all the places that you or your users might want to use | |
61 | the functionality implemented with `unsafe` code, because using a safe | |
62 | abstraction is safe. | |
63 | ||
74b04a01 | 64 | Let’s look at each of the five unsafe superpowers in turn. We’ll also look at |
13cf67c4 XL |
65 | some abstractions that provide a safe interface to unsafe code. |
66 | ||
67 | ### Dereferencing a Raw Pointer | |
68 | ||
9fa01778 XL |
69 | In Chapter 4, in the [“Dangling References”][dangling-references]<!-- ignore |
70 | --> section, we mentioned that the compiler ensures references are always | |
71 | valid. Unsafe Rust has two new types called *raw pointers* that are similar to | |
72 | references. As with references, raw pointers can be immutable or mutable and | |
73 | are written as `*const T` and `*mut T`, respectively. The asterisk isn’t the | |
74 | dereference operator; it’s part of the type name. In the context of raw | |
75 | pointers, *immutable* means that the pointer can’t be directly assigned to | |
76 | after being dereferenced. | |
13cf67c4 XL |
77 | |
78 | Different 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 | ||
86 | By opting out of having Rust enforce these guarantees, you can give up | |
87 | guaranteed safety in exchange for greater performance or the ability to | |
88 | interface with another language or hardware where Rust’s guarantees don’t apply. | |
89 | ||
90 | Listing 19-1 shows how to create an immutable and a mutable raw pointer from | |
91 | references. | |
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 | ||
99 | Notice that we don’t include the `unsafe` keyword in this code. We can create | |
100 | raw pointers in safe code; we just can’t dereference raw pointers outside an | |
101 | unsafe block, as you’ll see in a bit. | |
102 | ||
103 | We’ve created raw pointers by using `as` to cast an immutable and a mutable | |
104 | reference into their corresponding raw pointer types. Because we created them | |
105 | directly from references guaranteed to be valid, we know these particular raw | |
106 | pointers are valid, but we can’t make that assumption about just any raw | |
107 | pointer. | |
108 | ||
109 | Next, we’ll create a raw pointer whose validity we can’t be so certain of. | |
110 | Listing 19-2 shows how to create a raw pointer to an arbitrary location in | |
111 | memory. Trying to use arbitrary memory is undefined: there might be data at | |
112 | that address or there might not, the compiler might optimize the code so there | |
113 | is no memory access, or the program might error with a segmentation fault. | |
114 | Usually, 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 | |
121 | memory address</span> | |
122 | ||
123 | Recall that we can create raw pointers in safe code, but we can’t *dereference* | |
124 | raw pointers and read the data being pointed to. In Listing 19-3, we use the | |
125 | dereference 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 | ||
134 | Creating a pointer does no harm; it’s only when we try to access the value that | |
135 | it points at that we might end up dealing with an invalid value. | |
136 | ||
137 | Note also that in Listing 19-1 and 19-3, we created `*const i32` and `*mut i32` | |
138 | raw pointers that both pointed to the same memory location, where `num` is | |
139 | stored. 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 | |
141 | allow a mutable reference at the same time as any immutable references. With | |
142 | raw pointers, we can create a mutable pointer and an immutable pointer to the | |
143 | same location and change data through the mutable pointer, potentially creating | |
144 | a data race. Be careful! | |
145 | ||
146 | With all of these dangers, why would you ever use raw pointers? One major use | |
147 | case is when interfacing with C code, as you’ll see in the next section, | |
9fa01778 XL |
148 | [“Calling an Unsafe Function or |
149 | Method.”](#calling-an-unsafe-function-or-method)<!-- ignore --> Another case is | |
150 | when building up safe abstractions that the borrow checker doesn’t understand. | |
151 | We’ll introduce unsafe functions and then look at an example of a safe | |
152 | abstraction that uses unsafe code. | |
13cf67c4 XL |
153 | |
154 | ### Calling an Unsafe Function or Method | |
155 | ||
156 | The second type of operation that requires an unsafe block is calls to unsafe | |
157 | functions. Unsafe functions and methods look exactly like regular functions and | |
158 | methods, 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 | |
160 | need to uphold when we call this function, because Rust can’t guarantee we’ve | |
161 | met these requirements. By calling an unsafe function within an `unsafe` block, | |
162 | we’re saying that we’ve read this function’s documentation and take | |
163 | responsibility for upholding the function’s contracts. | |
164 | ||
165 | Here is an unsafe function named `dangerous` that doesn’t do anything in its | |
166 | body: | |
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 | ||
172 | We must call the `dangerous` function within a separate `unsafe` block. If we | |
173 | try 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 | ||
179 | By inserting the `unsafe` block around our call to `dangerous`, we’re asserting | |
180 | to Rust that we’ve read the function’s documentation, we understand how to use | |
181 | it properly, and we’ve verified that we’re fulfilling the contract of the | |
182 | function. | |
183 | ||
184 | Bodies of unsafe functions are effectively `unsafe` blocks, so to perform other | |
185 | unsafe 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 | ||
190 | Just because a function contains unsafe code doesn’t mean we need to mark the | |
191 | entire function as unsafe. In fact, wrapping unsafe code in a safe function is | |
192 | a common abstraction. As an example, let’s study a function from the standard | |
193 | library, `split_at_mut`, that requires some unsafe code and explore how we | |
194 | might implement it. This safe method is defined on mutable slices: it takes one | |
195 | slice and makes it two by splitting the slice at the index given as an | |
196 | argument. 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` | |
203 | function</span> | |
204 | ||
205 | We can’t implement this function using only safe Rust. An attempt might look | |
206 | something like Listing 19-5, which won’t compile. For simplicity, we’ll | |
207 | implement `split_at_mut` as a function rather than a method and only for slices | |
208 | of `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 | ||
217 | This function first gets the total length of the slice. Then it asserts that | |
218 | the index given as a parameter is within the slice by checking whether it’s | |
219 | less than or equal to the length. The assertion means that if we pass an index | |
e74abb32 | 220 | that is greater than the length to split the slice at, the function will panic |
13cf67c4 XL |
221 | before it attempts to use that index. |
222 | ||
223 | Then we return two mutable slices in a tuple: one from the start of the | |
224 | original slice to the `mid` index and another from `mid` to the end of the | |
225 | slice. | |
226 | ||
227 | When 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 | ||
233 | Rust’s borrow checker can’t understand that we’re borrowing different parts of | |
234 | the slice; it only knows that we’re borrowing from the same slice twice. | |
235 | Borrowing different parts of a slice is fundamentally okay because the two | |
236 | slices aren’t overlapping, but Rust isn’t smart enough to know this. When we | |
237 | know code is okay, but Rust doesn’t, it’s time to reach for unsafe code. | |
238 | ||
239 | Listing 19-6 shows how to use an `unsafe` block, a raw pointer, and some calls | |
240 | to 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 | |
247 | the `split_at_mut` function</span> | |
248 | ||
9fa01778 XL |
249 | Recall from [“The Slice Type”][the-slice-type]<!-- ignore --> section in |
250 | Chapter 4 that slices are a pointer to some data and the length of the slice. | |
251 | We use the `len` method to get the length of a slice and the `as_mut_ptr` | |
252 | method to access the raw pointer of a slice. In this case, because we have a | |
253 | mutable 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 | |
256 | We keep the assertion that the `mid` index is within the slice. Then we get to | |
257 | the unsafe code: the `slice::from_raw_parts_mut` function takes a raw pointer | |
258 | and a length, and it creates a slice. We use this function to create a slice | |
74b04a01 | 259 | that starts from `ptr` and is `mid` items long. Then we call the `add` |
13cf67c4 XL |
260 | method 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 | |
262 | items after `mid` as the length. | |
263 | ||
264 | The function `slice::from_raw_parts_mut` is unsafe because it takes a raw | |
74b04a01 | 265 | pointer and must trust that this pointer is valid. The `add` method on raw |
13cf67c4 XL |
266 | pointers is also unsafe, because it must trust that the offset location is also |
267 | a 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 |
269 | the 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 | |
271 | will be valid pointers to data within the slice. This is an acceptable and | |
272 | appropriate use of `unsafe`. | |
273 | ||
274 | Note 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 | |
276 | abstraction 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 | |
278 | data this function has access to. | |
279 | ||
280 | In contrast, the use of `slice::from_raw_parts_mut` in Listing 19-7 would | |
281 | likely crash when the slice is used. This code takes an arbitrary memory | |
282 | location 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 | |
289 | location</span> | |
290 | ||
291 | We don’t own the memory at this arbitrary location, and there is no guarantee | |
292 | that 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 | ||
297 | Sometimes, your Rust code might need to interact with code written in another | |
298 | language. For this, Rust has a keyword, `extern`, that facilitates the creation | |
299 | and use of a *Foreign Function Interface (FFI)*. An FFI is a way for a | |
300 | programming language to define functions and enable a different (foreign) | |
301 | programming language to call those functions. | |
302 | ||
303 | Listing 19-8 demonstrates how to set up an integration with the `abs` function | |
304 | from the C standard library. Functions declared within `extern` blocks are | |
305 | always unsafe to call from Rust code. The reason is that other languages don’t | |
306 | enforce Rust’s rules and guarantees, and Rust can’t check them, so | |
307 | responsibility 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 | |
316 | defined in another language</span> | |
317 | ||
318 | Within the `extern "C"` block, we list the names and signatures of external | |
319 | functions from another language we want to call. The `"C"` part defines which | |
320 | *application binary interface (ABI)* the external function uses: the ABI | |
321 | defines how to call the function at the assembly level. The `"C"` ABI is the | |
322 | most 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 | ||
351 | Until now, we’ve not talked about *global variables*, which Rust does support | |
352 | but can be problematic with Rust’s ownership rules. If two threads are | |
353 | accessing the same mutable global variable, it can cause a data race. | |
354 | ||
355 | In Rust, global variables are called *static* variables. Listing 19-9 shows an | |
356 | example declaration and use of a static variable with a string slice as a | |
357 | value. | |
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 | |
366 | variable</span> | |
367 | ||
368 | Static variables are similar to constants, which we discussed in the | |
dc9dc135 XL |
369 | [“Differences Between Variables and |
370 | Constants”][differences-between-variables-and-constants]<!-- ignore --> | |
371 | section in Chapter 3. The names of static variables are in | |
372 | `SCREAMING_SNAKE_CASE` by convention, and we *must* annotate the variable’s | |
373 | type, which is `&'static str` in this example. Static variables can only store | |
374 | references with the `'static` lifetime, which means the Rust compiler can | |
375 | figure out the lifetime; we don’t need to annotate it explicitly. Accessing an | |
376 | immutable static variable is safe. | |
13cf67c4 XL |
377 | |
378 | Constants and immutable static variables might seem similar, but a subtle | |
379 | difference is that values in a static variable have a fixed address in memory. | |
380 | Using the value will always access the same data. Constants, on the other hand, | |
381 | are allowed to duplicate their data whenever they’re used. | |
382 | ||
383 | Another difference between constants and static variables is that static | |
384 | variables can be mutable. Accessing and modifying mutable static variables is | |
385 | *unsafe*. Listing 19-10 shows how to declare, access, and modify a mutable | |
386 | static 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 | |
395 | static variable is unsafe</span> | |
396 | ||
397 | As with regular variables, we specify mutability using the `mut` keyword. Any | |
398 | code that reads or writes from `COUNTER` must be within an `unsafe` block. This | |
399 | code compiles and prints `COUNTER: 3` as we would expect because it’s single | |
400 | threaded. Having multiple threads access `COUNTER` would likely result in data | |
401 | races. | |
402 | ||
403 | With mutable data that is globally accessible, it’s difficult to ensure there | |
404 | are no data races, which is why Rust considers mutable static variables to be | |
405 | unsafe. Where possible, it’s preferable to use the concurrency techniques and | |
406 | thread-safe smart pointers we discussed in Chapter 16 so the compiler checks | |
407 | that data accessed from different threads is done safely. | |
408 | ||
409 | ### Implementing an Unsafe Trait | |
410 | ||
411 | The final action that works only with `unsafe` is implementing an unsafe trait. | |
412 | A trait is unsafe when at least one of its methods has some invariant that the | |
413 | compiler 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 | |
422 | trait</span> | |
423 | ||
424 | By using `unsafe impl`, we’re promising that we’ll uphold the invariants that | |
425 | the compiler can’t verify. | |
426 | ||
427 | As an example, recall the `Sync` and `Send` marker traits we discussed in the | |
dc9dc135 XL |
428 | [“Extensible Concurrency with the `Sync` and `Send` |
429 | Traits”][extensible-concurrency-with-the-sync-and-send-traits]<!-- ignore --> | |
430 | section in Chapter 16: the compiler implements these traits automatically if | |
431 | our types are composed entirely of `Send` and `Sync` types. If we implement a | |
432 | type that contains a type that is not `Send` or `Sync`, such as raw pointers, | |
433 | and we want to mark that type as `Send` or `Sync`, we must use `unsafe`. Rust | |
434 | can’t verify that our type upholds the guarantees that it can be safely sent | |
435 | across threads or accessed from multiple threads; therefore, we need to do | |
436 | those checks manually and indicate as such with `unsafe`. | |
13cf67c4 | 437 | |
74b04a01 XL |
438 | ### Accessing Fields of a Union |
439 | ||
440 | A `union` is similar to a `struct`, but only one declared field is used in a | |
441 | particular instance at one time. Unions are primarily used to interface with | |
442 | unions in C code. Accessing union fields is unsafe because Rust can’t guarantee | |
443 | the type of the data currently being stored in the union instance. You can | |
444 | learn more about unions in [the reference][reference]. | |
445 | ||
13cf67c4 XL |
446 | ### When to Use Unsafe Code |
447 | ||
74b04a01 | 448 | Using `unsafe` to take one of the five actions (superpowers) just discussed |
13cf67c4 XL |
449 | isn’t wrong or even frowned upon. But it is trickier to get `unsafe` code |
450 | correct because the compiler can’t help uphold memory safety. When you have a | |
451 | reason to use `unsafe` code, you can do so, and having the explicit `unsafe` | |
74b04a01 | 452 | annotation makes it easier to track down the source of problems when they occur. |
9fa01778 XL |
453 | |
454 | [dangling-references]: | |
455 | ch04-02-references-and-borrowing.html#dangling-references | |
456 | [differences-between-variables-and-constants]: | |
457 | ch03-01-variables-and-mutability.html#differences-between-variables-and-constants | |
458 | [extensible-concurrency-with-the-sync-and-send-traits]: | |
459 | ch16-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 |