mirror of https://github.com/rust-lang/nomicon
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
2.3 KiB
59 lines
2.3 KiB
8 years ago
|
# What Unsafe Rust Can Do
|
||
|
|
||
|
The only things that are different in Unsafe Rust are that you can:
|
||
|
|
||
|
* Dereference raw pointers
|
||
|
* Call `unsafe` functions (including C functions, compiler intrinsics, and the raw allocator)
|
||
|
* Implement `unsafe` traits
|
||
|
* Mutate statics
|
||
|
|
||
|
That's it. The reason these operations are relegated to Unsafe is that misusing
|
||
|
any of these things will cause the ever dreaded Undefined Behavior. Invoking
|
||
|
Undefined Behavior gives the compiler full rights to do arbitrarily bad things
|
||
|
to your program. You definitely *should not* invoke Undefined Behavior.
|
||
|
|
||
|
Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core
|
||
|
language cares about is preventing the following things:
|
||
|
|
||
|
* Dereferencing null, dangling, or unaligned pointers
|
||
|
* Reading [uninitialized memory][]
|
||
|
* Breaking the [pointer aliasing rules][]
|
||
|
* Producing invalid primitive values:
|
||
|
* dangling/null references
|
||
|
* a `bool` that isn't 0 or 1
|
||
|
* an undefined `enum` discriminant
|
||
|
* a `char` outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF]
|
||
|
* A non-utf8 `str`
|
||
|
* Unwinding into another language
|
||
|
* Causing a [data race][race]
|
||
|
|
||
|
That's it. That's all the causes of Undefined Behavior baked into Rust. Of
|
||
|
course, unsafe functions and traits are free to declare arbitrary other
|
||
|
constraints that a program must maintain to avoid Undefined Behavior. For
|
||
|
instance, the allocator APIs declare that deallocating unallocated memory is
|
||
|
Undefined Behavior.
|
||
|
|
||
|
However, violations of these constraints generally will just transitively lead to one of
|
||
|
the above problems. Some additional constraints may also derive from compiler
|
||
|
intrinsics that make special assumptions about how code can be optimized. For instance,
|
||
|
Vec and Box make use of intrinsics that require their pointers to be non-null at all times.
|
||
|
|
||
|
Rust is otherwise quite permissive with respect to other dubious operations.
|
||
|
Rust considers it "safe" to:
|
||
|
|
||
|
* Deadlock
|
||
|
* Have a [race condition][race]
|
||
|
* Leak memory
|
||
|
* Fail to call destructors
|
||
|
* Overflow integers
|
||
|
* Abort the program
|
||
|
* Delete the production database
|
||
|
|
||
|
However any program that actually manages to do such a thing is *probably*
|
||
|
incorrect. Rust provides lots of tools to make these things rare, but
|
||
|
these problems are considered impractical to categorically prevent.
|
||
|
|
||
|
[pointer aliasing rules]: references.html
|
||
|
[uninitialized memory]: uninitialized.html
|
||
|
[race]: races.html
|