@@ -8,27 +8,32 @@ Creating pointers is safe, but dereferencing them requires `unsafe`:
8
8
9
9
``` rust,editable
10
10
fn main() {
11
- let mut s = String::from("careful!") ;
11
+ let mut x = 10 ;
12
12
13
- let r1 = &raw mut s ;
14
- let r2 = r1 as *const String ;
13
+ let p1: *mut i32 = &raw mut x ;
14
+ let p2 = p1 as *const i32 ;
15
15
16
- // SAFETY: r1 and r2 were obtained from references and so are guaranteed to
17
- // be non-null and properly aligned, the objects underlying the references
18
- // from which they were obtained are live throughout the whole unsafe
19
- // block, and they are not accessed either through the references or
20
- // concurrently through any other pointers.
16
+ // SAFETY: p1 and p2 were created by taking raw pointers to a local, so they
17
+ // are guaranteed to be non-null, aligned, and point into a single (stack-)
18
+ // allocated object.
19
+ //
20
+ // The object underlying the raw pointers lives for the entire function, so
21
+ // it is not deallocated while the raw pointers still exist. It is not
22
+ // accessed through references while the raw pointers exist, nor is it
23
+ // accessed from other threads concurrently.
21
24
unsafe {
22
- println!("r1 is: {}", *r1);
23
- *r1 = String::from("uhoh");
24
- println!("r2 is: {}", *r2);
25
+ dbg!(*p1);
26
+ *p1 = 6;
27
+ // Mutation may soundly be observed through a raw pointer, like in C.
28
+ dbg!(*p2);
25
29
}
26
30
27
- // NOT SAFE . DO NOT DO THIS.
31
+ // UNSOUND . DO NOT DO THIS.
28
32
/*
29
- let r3: &String = unsafe { &*r1 };
30
- drop(s);
31
- println!("r3 is: {}", *r3);
33
+ let r: &i32 = unsafe { &*p1 };
34
+ dbg!(r);
35
+ x = 50;
36
+ dbg!(r); // Object underlying the reference has been mutated. This is UB.
32
37
*/
33
38
}
34
39
```
@@ -52,8 +57,11 @@ In the case of pointer dereferences, this means that the pointers must be
52
57
53
58
In most cases the pointer must also be properly aligned.
54
59
55
- The "NOT SAFE" section gives an example of a common kind of UB bug: ` *r1 ` has
56
- the ` 'static ` lifetime, so ` r3 ` has type ` &'static String ` , and thus outlives
57
- ` s ` . Creating a reference from a pointer requires _ great care_ .
60
+ The "UNSOUND" section gives an example of a common kind of UB bug: naïvely
61
+ taking a reference to the dereference of a raw pointer sidesteps the compiler's
62
+ knowledge of what object the reference is actually pointing to. As such, the
63
+ borrow checker does not freeze ` x ` and so we are able to modify it despite the
64
+ existence of a reference to it. Creating a reference from a pointer requires
65
+ _ great care_ .
58
66
59
67
</details >
0 commit comments