]> git.lizzy.rs Git - rust.git/blob - src/doc/nomicon/meet-safe-and-unsafe.md
Nomicon: Fix Links
[rust.git] / src / doc / nomicon / meet-safe-and-unsafe.md
1 % Meet Safe and Unsafe
2
3 Programmers in safe "high-level" languages face a fundamental dilemma. On one
4 hand, it would be *really* great to just say what you want and not worry about
5 how it's done. On the other hand, that can lead to unacceptably poor
6 performance. It may be necessary to drop down to less clear or idiomatic
7 practices to get the performance characteristics you want. Or maybe you just
8 throw up your hands in disgust and decide to shell out to an implementation in
9 a less sugary-wonderful *unsafe* language.
10
11 Worse, when you want to talk directly to the operating system, you *have* to
12 talk to an unsafe language: *C*. C is ever-present and unavoidable. It's the
13 lingua-franca of the programming world.
14 Even other safe languages generally expose C interfaces for the world at large!
15 Regardless of why you're doing it, as soon as your program starts talking to
16 C it stops being safe.
17
18 With that said, Rust is *totally* a safe programming language.
19
20 Well, Rust *has* a safe programming language. Let's step back a bit.
21
22 Rust can be thought of as being composed of two programming languages: *Safe
23 Rust* and *Unsafe Rust*. Safe Rust is For Reals  Totally Safe. Unsafe Rust,
24 unsurprisingly, is *not* For Reals Totally Safe.  In fact, Unsafe Rust lets you
25 do some really crazy unsafe things.
26
27 Safe Rust is the *true* Rust programming language. If all you do is write Safe
28 Rust, you will never have to worry about type-safety or memory-safety. You will
29 never endure a null or dangling pointer, or any of that Undefined Behaviour
30 nonsense.
31
32 *That's totally awesome.*
33
34 The standard library also gives you enough utilities out-of-the-box that you'll
35 be able to write awesome high-performance applications and libraries in pure
36 idiomatic Safe Rust.
37
38 But maybe you want to talk to another language. Maybe you're writing a
39 low-level abstraction not exposed by the standard library. Maybe you're
40 *writing* the standard library (which is written entirely in Rust). Maybe you
41 need to do something the type-system doesn't understand and just *frob some dang
42 bits*. Maybe you need Unsafe Rust.
43
44 Unsafe Rust is exactly like Safe Rust with all the same rules and semantics.
45 However Unsafe Rust lets you do some *extra* things that are Definitely Not Safe.
46
47 The only things that are different in Unsafe Rust are that you can:
48
49 * Dereference raw pointers
50 * Call `unsafe` functions (including C functions, intrinsics, and the raw allocator)
51 * Implement `unsafe` traits
52 * Mutate statics
53
54 That's it. The reason these operations are relegated to Unsafe is that misusing
55 any of these things will cause the ever dreaded Undefined Behaviour. Invoking
56 Undefined Behaviour gives the compiler full rights to do arbitrarily bad things
57 to your program. You definitely *should not* invoke Undefined Behaviour.
58
59 Unlike C, Undefined Behaviour is pretty limited in scope in Rust. All the core
60 language cares about is preventing the following things:
61
62 * Dereferencing null or dangling pointers
63 * Reading [uninitialized memory]
64 * Breaking the [pointer aliasing rules]
65 * Producing invalid primitive values:
66     * dangling/null references
67     * a `bool` that isn't 0 or 1
68     * an undefined `enum` discriminant
69     * a `char` outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF]
70     * A non-utf8 `str`
71 * Unwinding into another language
72 * Causing a [data race][race]
73
74 That's it. That's all the causes of Undefined Behaviour baked into Rust. Of
75 course, unsafe functions and traits are free to declare arbitrary other
76 constraints that a program must maintain to avoid Undefined Behaviour. However,
77 generally violations of these constraints will just transitively lead to one of
78 the above problems. Some additional constraints may also derive from compiler
79 intrinsics that make special assumptions about how code can be optimized.
80
81 Rust is otherwise quite permissive with respect to other dubious operations.
82 Rust considers it "safe" to:
83
84 * Deadlock
85 * Have a [race condition][race]
86 * Leak memory
87 * Fail to call destructors
88 * Overflow integers
89 * Abort the program
90 * Delete the production database
91
92 However any program that actually manages to do such a thing is *probably*
93 incorrect. Rust provides lots of tools to make these things rare, but
94 these problems are considered impractical to categorically prevent.
95
96 [pointer aliasing rules]: references.html
97 [uninitialized memory]: uninitialized.html
98 [race]: races.html