]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/raw-pointers.md
Resolve unused_parens compilation warning
[rust.git] / src / doc / trpl / raw-pointers.md
1 % Raw Pointers
2
3 Rust has a number of different smart pointer types in its standard library, but
4 there are two types that are extra-special. Much of Rust’s safety comes from
5 compile-time checks, but raw pointers don’t have such guarantees, and are
6 [unsafe][unsafe] to use.
7
8 `*const T` and `*mut T` are called ‘raw pointers’ in Rust. Sometimes, when
9 writing certain kinds of libraries, you’ll need to get around Rust’s safety
10 guarantees for some reason. In this case, you can use raw pointers to implement
11 your library, while exposing a safe interface for your users. For example, `*`
12 pointers are allowed to alias, allowing them to be used to write
13 shared-ownership types, and even thread-safe shared memory types (the `Rc<T>`
14 and `Arc<T>` types are both implemented entirely in Rust).
15
16 Here are some things to remember about raw pointers that are different than
17 other pointer types. They:
18
19 - are not guaranteed to point to valid memory and are not even
20   guaranteed to be non-null (unlike both `Box` and `&`);
21 - do not have any automatic clean-up, unlike `Box`, and so require
22   manual resource management;
23 - are plain-old-data, that is, they don't move ownership, again unlike
24   `Box`, hence the Rust compiler cannot protect against bugs like
25   use-after-free;
26 - lack any form of lifetimes, unlike `&`, and so the compiler cannot
27   reason about dangling pointers; and
28 - have no guarantees about aliasing or mutability other than mutation
29   not being allowed directly through a `*const T`.
30
31 # Basics
32
33 Creating a raw pointer is perfectly safe:
34
35 ```rust
36 let x = 5;
37 let raw = &x as *const i32;
38
39 let mut y = 10;
40 let raw_mut = &mut y as *mut i32;
41 ```
42
43 However, dereferencing one is not. This won’t work:
44
45 ```rust,ignore
46 let x = 5;
47 let raw = &x as *const i32;
48
49 println!("raw points at {}", *raw);
50 ```
51
52 It gives this error:
53
54 ```text
55 error: dereference of raw pointer requires unsafe function or block [E0133]
56      println!("raw points at {}", *raw);
57                                   ^~~~
58 ```
59
60 When you dereference a raw pointer, you’re taking responsibility that it’s not
61 pointing somewhere that would be incorrect. As such, you need `unsafe`:
62
63 ```rust
64 let x = 5;
65 let raw = &x as *const i32;
66
67 let points_at = unsafe { *raw };
68
69 println!("raw points at {}", points_at);
70 ```
71
72 For more operations on raw pointers, see [their API documentation][rawapi].
73
74 [unsafe]: unsafe.html
75 [rawapi]: ../std/primitive.pointer.html
76
77 # FFI
78
79 Raw pointers are useful for FFI: Rust’s `*const T` and `*mut T` are similar to
80 C’s `const T*` and `T*`, respectively. For more about this use, consult the
81 [FFI chapter][ffi].
82
83 [ffi]: ffi.html
84
85 # References and raw pointers
86
87 At runtime, a raw pointer `*` and a reference pointing to the same piece of
88 data have an identical representation. In fact, an `&T` reference will
89 implicitly coerce to an `*const T` raw pointer in safe code and similarly for
90 the `mut` variants (both coercions can be performed explicitly with,
91 respectively, `value as *const T` and `value as *mut T`).
92
93 Going the opposite direction, from `*const` to a reference `&`, is not safe. A
94 `&T` is always valid, and so, at a minimum, the raw pointer `*const T` has to
95 point to a valid instance of type `T`. Furthermore, the resulting pointer must
96 satisfy the aliasing and mutability laws of references. The compiler assumes
97 these properties are true for any references, no matter how they are created,
98 and so any conversion from raw pointers is asserting that they hold. The
99 programmer *must* guarantee this.
100
101 The recommended method for the conversion is
102
103 ```rust
104 let i: u32 = 1;
105
106 // explicit cast
107 let p_imm: *const u32 = &i as *const u32;
108 let mut m: u32 = 2;
109
110 // implicit coercion
111 let p_mut: *mut u32 = &mut m;
112
113 unsafe {
114     let ref_imm: &u32 = &*p_imm;
115     let ref_mut: &mut u32 = &mut *p_mut;
116 }
117 ```
118
119 The `&*x` dereferencing style is preferred to using a `transmute`. The latter
120 is far more powerful than necessary, and the more restricted operation is
121 harder to use incorrectly; for example, it requires that `x` is a pointer
122 (unlike `transmute`).