@@ -88,10 +88,9 @@ By opting out of having Rust enforce these guarantees, you can give up
8888guaranteed safety in exchange for greater performance or the ability to
8989interface with another language or hardware where Rust’s guarantees don’t apply.
9090
91- Listing 20-1 shows how to create an immutable and a mutable raw pointer from
92- references.
91+ Listing 20-1 shows how to create an immutable and a mutable raw pointer.
9392
94- <Listing number =" 20-1 " caption =" Creating raw pointers from references " >
93+ <Listing number =" 20-1 " caption =" Creating raw pointers with the raw borrow operators " >
9594
9695``` rust
9796{{#rustdoc_include .. / listings / ch20 - advanced - features / listing - 20 - 01 / src / main . rs: here }}
@@ -103,19 +102,20 @@ Notice that we don’t include the `unsafe` keyword in this code. We can create
103102raw pointers in safe code; we just can’t dereference raw pointers outside an
104103unsafe block, as you’ll see in a bit.
105104
106- We’ve created raw pointers by using ` as ` to cast an immutable and a mutable
107- reference into their corresponding raw pointer types. Because we created them
108- directly from references guaranteed to be valid, we know these particular raw
109- pointers are valid, but we can’t make that assumption about just any raw
110- pointer.
105+ We’ve created raw pointers by using the raw borrow operators: ` &raw const num `
106+ creates a ` *const i32 ` immutable raw pointer, and ` &raw mut num ` creates a `&mut
107+ i32` mutable raw pointer. Because we created them directly from a local
108+ variable, we know these particular raw pointers are valid, but we can’t make
109+ that assumption about just any raw pointer.
111110
112111To demonstrate this, next we’ll create a raw pointer whose validity we can’t be
113- so certain of. Listing 20-2 shows how to create a raw pointer to an arbitrary
112+ so certain of, using ` as ` to cast a value instead of using the raw reference
113+ operators. Listing 20-2 shows how to create a raw pointer to an arbitrary
114114location in memory. Trying to use arbitrary memory is undefined: there might be
115- data at that address or there might not, the compiler might optimize the code
116- so there is no memory access, or the program might error with a segmentation
117- fault. Usually, there is no good reason to write code like this, but it is
118- possible.
115+ data at that address or there might not, the compiler might optimize the code so
116+ there is no memory access, or the program might error with a segmentation fault.
117+ Usually, there is no good reason to write code like this, especially in cases
118+ where you can use a raw borrow operator instead, but it is possible.
119119
120120<Listing number =" 20-2 " caption =" Creating a raw pointer to an arbitrary memory address " >
121121
@@ -401,7 +401,15 @@ As with regular variables, we specify mutability using the `mut` keyword. Any
401401code that reads or writes from `COUNTER ` must be within an `unsafe ` block. This
402402code compiles and prints `COUNTER : 3` as we would expect because it’s single
403403threaded. Having multiple threads access `COUNTER ` would likely result in data
404- races.
404+ races, so it is undefined behavior. Therefore , we need to mark the entire
405+ function as `unsafe `, and document the safety limitation, so anyone calling the
406+ function knows what they are and are not allowed to do safely.
407+
408+ Whenever we write an unsafe function, it is idiomatic to write a comment
409+ starting with `SAFETY ` and explaining what the caller needs to do to call the
410+ function safely. Likewise , whenever we perform an unsafe operation, it is
411+ idiomatic to write a comment starting with `SAFETY ` to explain how the safety
412+ rules are upheld.
405413
406414With mutable data that is globally accessible, it’s difficult to ensure there
407415are no data races, which is why Rust considers mutable static variables to be
@@ -448,13 +456,56 @@ interface with unions in C code. Accessing union fields is unsafe because Rust
448456can ’t guarantee the type of the data currently being stored in the union
449457instance . You can learn more about unions in [the Rust Reference ][reference ].
450458
459+ ### Using Miri to check unsafe code
460+
461+ When writing unsafe code , you might want to check that what you have written
462+ actually is safe and correct . One of the best ways to do that is to use
463+ [Miri ][miri], an official Rust tool for detecting undefined behavior. Whereas
464+ the borrow checker is a * static * tool which works at compile time, Miri is a
465+ * dynamic* tool which works at runtime. It checks your code by running your
466+ program, or its test suite, and detecting when you violate the rules its
467+ understands about how Rust should work.
468+
469+ Using Miri requires a nightly build of Rust (which we talk about more in
470+ [Appendix G : How Rust is Made and “Nightly Rust ”][nightly]). You can install
471+ both a nightly version of Rust and the Miri tool by typing `rustup + nightly
472+ component add miri`. This does not change what version of Rust your project
473+ uses; it only adds the tool to your system so you can use it when you want to.
474+ You can run Miri on a project by typing `cargo + nightly miri run` or `cargo
475+ + nightly miri test`.
476+
477+ For an example of how helpful this can be, consider what happens when we run it
478+ against Listing 20- 10:
479+
480+ ```console
481+ {{#include .. / listings/ ch20- advanced- features/ listing- 20- 10/ output. txt}}
482+ ```
483+
484+ It helpfully and correctly notices that we have shared references to mutable
485+ data, and warns about it. In this case, it does not tell us how to fix the
486+ problem, but it means that we know there is a possible issue and can think about
487+ how to make sure it is safe. In other cases, it can actually tell us that some
488+ code is * sure* to be wrong and make recommendations about how to fix it.
489+
490+ Miri doesn’t catch * everything* you might get wrong when writing unsafe code.
491+ For one thing, since it is a dynamic check, it only catches problems with code
492+ that actually gets run. That means you will need to use it in conjunction with
493+ good testing techniques to increase your confidence about the unsafe code you
494+ have written. For another thing, it does not cover every possible way your code
495+ can be unsound. If Miri * does* catch a problem, you know there’s a bug, but just
496+ because Miri * doesn’t* catch a bug doesn’t mean there isn’t a problem. Miri can
497+ catch a lot, though. Try running it on the other examples of unsafe code in this
498+ chapter and see what it says!
499+
451500### When to Use Unsafe Code
452501
453502Using `unsafe ` to take one of the five actions (superpowers) just discussed
454503isn’t wrong or even frowned upon. But it is trickier to get `unsafe ` code
455504correct because the compiler can’t help uphold memory safety. When you have a
456505reason to use `unsafe ` code, you can do so, and having the explicit `unsafe `
457506annotation makes it easier to track down the source of problems when they occur.
507+ Whenever you write unsafe code, you can use Miri to help you be more confident
508+ that the code you have written upholds Rust ’s rules.
458509
459510[dangling- references]:
460511ch04- 02- references- and- borrowing. html#dangling- references
@@ -464,3 +515,5 @@ ch03-01-variables-and-mutability.html#constants
464515ch16- 04- extensible- concurrency- sync- and- send. html#extensible- concurrency- with- the- sync- and- send- traits
465516[the- slice- type ]: ch04- 03- slices. html#the- slice- type
466517[reference]: .. / reference/ items/ unions. html
518+ [miri]: https: // github.com/rust-lang/miri
519+ [nightly]: appendix- 07- nightly- rust. html
0 commit comments