diff --git a/listings/ch20-advanced-features/listing-20-11/src/main.rs b/listings/ch20-advanced-features/listing-20-11/src/main.rs index 360e3548fc..4e292b18bf 100644 --- a/listings/ch20-advanced-features/listing-20-11/src/main.rs +++ b/listings/ch20-advanced-features/listing-20-11/src/main.rs @@ -4,13 +4,15 @@ static mut COUNTER: u32 = 0; /// behavior, so you *must* guarantee you only call it from a single thread at /// a time. unsafe fn add_to_count(inc: u32) { - COUNTER += inc; + unsafe { + COUNTER += inc; + } } fn main() { unsafe { // SAFETY: This is only called from a single thread in `main`. add_to_count(3); - println!("COUNTER: {}", COUNTER); + println!("COUNTER: {}", *(&raw const COUNTER)); } } diff --git a/src/ch20-01-unsafe-rust.md b/src/ch20-01-unsafe-rust.md index 703c957094..724dd10999 100644 --- a/src/ch20-01-unsafe-rust.md +++ b/src/ch20-01-unsafe-rust.md @@ -424,12 +424,13 @@ static variable named `COUNTER`. </Listing> As with regular variables, we specify mutability using the `mut` keyword. Any -code that reads or writes from `COUNTER` must be within an `unsafe` block. This -code compiles and prints `COUNTER: 3` as we would expect because it’s single -threaded. Having multiple threads access `COUNTER` would likely result in data -races, so it is undefined behavior. Therefore, we need to mark the entire -function as `unsafe`, and document the safety limitation, so anyone calling the -function knows what they are and are not allowed to do safely. +code that reads or writes from `COUNTER` must be within an `unsafe` block. The +code in Listing 20-11 compiles and prints `COUNTER: 3` as we would expect +because it’s single threaded. Having multiple threads access `COUNTER` would +likely result in data races, so it is undefined behavior. Therefore, we need to +mark the entire function as `unsafe`, and document the safety limitation, so +anyone calling the function knows what they are and are not allowed to do +safely. Whenever we write an unsafe function, it is idiomatic to write a comment starting with `SAFETY` and explaining what the caller needs to do to call the @@ -437,6 +438,13 @@ function safely. Likewise, whenever we perform an unsafe operation, it is idiomatic to write a comment starting with `SAFETY` to explain how the safety rules are upheld. +Additionally, the compiler will not allow you to create references to a mutable +static variable. You can only access it via a raw pointer, created with one of +the raw borrow operators. That includes in cases where the reference is created +invisibly, as when it is used in the `println!` in this code listing. The +requirement that references to static mutable variables can only be created via +raw pointers helps make the safety requirements for using them more obvious. + With mutable data that is globally accessible, it’s difficult to ensure there are no data races, which is why Rust considers mutable static variables to be unsafe. Where possible, it’s preferable to use the concurrency techniques and