# Introduction
Rust aims to provide safe abstractions over the low-level details of
-the CPU and operating system, but sometimes one is forced to drop down
-and write code at that level (those abstractions have to be created
-somehow). This guide aims to provide an overview of the dangers and
-power one gets with Rust's unsafe subset.
+the CPU and operating system, but sometimes one needs to drop down and
+write code at that level. This guide aims to provide an overview of
+the dangers and power one gets with Rust's unsafe subset.
Rust provides an escape hatch in the form of the `unsafe { ... }`
-block which allows the programmer to dodge some of the compilers
+block which allows the programmer to dodge some of the compiler's
checks and do a wide range of operations, such as:
- dereferencing [raw pointers](#raw-pointers)
- [inline assembly](#inline-assembly)
Note that an `unsafe` block does not relax the rules about lifetimes
-of `&` and the freezing of borrowed data, it just allows the use of
-additional techniques for skirting the compiler's watchful eye. Any
-use of `unsafe` is the programmer saying "I know more than you" to the
-compiler, and, as such, the programmer should be very sure that they
-actually do know more about why that piece of code is valid.
+of `&` and the freezing of borrowed data.
-In general, one should try to minimize the amount of unsafe code in a
+Any use of `unsafe` is the programmer saying "I know more than you" to
+the compiler, and, as such, the programmer should be very sure that
+they actually do know more about why that piece of code is valid. In
+general, one should try to minimize the amount of unsafe code in a
code base; preferably by using the bare minimum `unsafe` blocks to
build safe interfaces.
## References
-One of Rust's biggest goals as a language is ensuring memory safety,
-achieved in part via [the lifetime system](guide-lifetimes.html) which
-every `&` references has associated with it. This system is how the
+One of Rust's biggest features is memory safety. This is achieved in
+part via [the lifetime system](guide-lifetimes.html), which is how the
compiler can guarantee that every `&` reference is always valid, and,
for example, never pointing to freed memory.
-These restrictions on `&` have huge advantages. However, there's no
-free lunch club. For example, `&` isn't a valid replacement for C's
-pointers, and so cannot be used for FFI, in general. Additionally,
-both immutable (`&`) and mutable (`&mut`) references have some
-aliasing and freezing guarantees, required for memory safety.
+These restrictions on `&` have huge advantages. However, they also
+constrain how we can use them. For example, `&` doesn't behave
+identically to C's pointers, and so cannot be used for pointers in
+foreign function interfaces (FFI). Additionally, both immutable (`&`)
+and mutable (`&mut`) references have some aliasing and freezing
+guarantees, required for memory safety.
In particular, if you have an `&T` reference, then the `T` must not be
modified through that reference or any other reference. There are some
mutability by replacing compile time guarantees with dynamic checks at
runtime.
-An `&mut` reference has a stronger requirement: when an object has an
+An `&mut` reference has a different constraint: when an object has an
`&mut T` pointing into it, then that `&mut` reference must be the only
such usable path to that object in the whole program. That is, an
`&mut` cannot alias with any other references.
Fortunately, they come with a redeeming feature: the weaker guarantees
mean weaker restrictions. The missing restrictions make raw pointers
-appropriate as a building block for (carefully!) implementing things
-like smart pointers and vectors inside libraries. For example, `*`
-pointers are allowed to alias, allowing them to be used to write
-shared-ownership types like reference counted and garbage collected
-pointers, and even thread-safe shared memory types (`Rc` and the `Arc`
-types are both implemented entirely in Rust).
+appropriate as a building block for implementing things like smart
+pointers and vectors inside libraries. For example, `*` pointers are
+allowed to alias, allowing them to be used to write shared-ownership
+types like reference counted and garbage collected pointers, and even
+thread-safe shared memory types (`Rc` and the `Arc` types are both
+implemented entirely in Rust).
There are two things that you are required to be careful about
(i.e. require an `unsafe { ... }` block) with raw pointers:
- dereferencing: they can have any value: so possible results include
a crash, a read of uninitialised memory, a use-after-free, or
- reading data as normal (and one hopes happens).
+ reading data as normal.
- pointer arithmetic via the `offset` [intrinsic](#intrinsics) (or
`.offset` method): this intrinsic uses so-called "in-bounds"
arithmetic, that is, it is only defined behaviour if the result is
- store pointers privately (i.e. not in public fields of public
structs), so that you can see and control all reads and writes to
the pointer in one place.
-- use `assert!()` a lot: once you've thrown away the protection of the
- compiler & type-system via `unsafe { ... }` you're left with just
- your wits and your `assert!()`s, any bug is potentially exploitable.
+- use `assert!()` a lot: since you can't rely on the protection of the
+ compiler & type-system to ensure that your `unsafe` code is correct
+ at compile-time, use `assert!()` to verify that it is doing the
+ right thing at run-time.
- implement the `Drop` for resource clean-up via a destructor, and use
RAII (Resource Acquisition Is Initialization). This reduces the need
for any manual memory management by users, and automatically ensures
Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
crate to allow) and of course requires an `unsafe` block.
-> **Note**: the examples here are given in x86/x86-64 assembly, but all
-> platforms are supported.
+> **Note**: the examples here are given in x86/x86-64 assembly, but
+> all platforms are supported.
## Assembly template
> parts of the language may never be full specified and so details may
> differ wildly between implementations (and even versions of `rustc`
> itself).
->
+>
> Furthermore, this is just an overview; the best form of
> documentation for specific instances of these features are their
> definitions and uses in `std`.
```
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
-return a valid pointer, and so needs to do the check
-internally.
+return a valid pointer, and so needs to do the check internally.
Other features provided by lang items include: