@@ -70,6 +70,57 @@ let a = && && mut 10;
70
70
let a = & & & & mut 10 ;
71
71
```
72
72
73
+ ### Raw address-of operators
74
+
75
+ Related to the borrow operators are the raw address-of operators, which do not
76
+ have first-class syntax, but are exposed via the macros ` ptr::addr_of!(expr) `
77
+ and ` ptr::addr_of_mut!(expr) ` . Like with ` & ` /` &mut ` , the expression is evaluated
78
+ in place expression context. The difference is that ` & ` /` &mut ` create
79
+ * references* of type ` &T ` /` &mut T ` , while ` ptr::addr_of!(expr) ` creates a
80
+ (const) raw pointer of type ` *const T ` and ` ptr::addr_of_mut!(expr) ` creates a
81
+ mutable raw pointer of type ` *mut T ` .
82
+
83
+ The raw address-of operators must be used whenever the place expression denotes
84
+ a place that is not properly aligned or does not store a valid value as
85
+ determined by its type. In those situations, using a borrow operator would
86
+ cause [ undefined behavior] by creating an invalid reference, but a raw pointer
87
+ may still be constructed using an address-of operator.
88
+
89
+ ** Example of creating a raw pointer to an unaligned place (through a ` packed ` struct):**
90
+
91
+ ``` rust
92
+ use std :: ptr;
93
+
94
+ #[repr(packed)]
95
+ struct Packed {
96
+ f1 : u8 ,
97
+ f2 : u16 ,
98
+ }
99
+
100
+ let packed = Packed { f1 : 1 , f2 : 2 };
101
+ // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
102
+ let raw_f2 = ptr :: addr_of! (packed . f2);
103
+ assert_eq! (unsafe { raw_f2 . read_unaligned () }, 2 );
104
+ ```
105
+
106
+ ** Example of creating a raw pointer to a place that does not contain a valid value:**
107
+
108
+ ``` rust
109
+ use std :: {ptr, mem :: MaybeUninit };
110
+
111
+ struct Demo {
112
+ field : bool ,
113
+ }
114
+
115
+ let mut uninit = MaybeUninit :: <Demo >:: uninit ();
116
+ // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
117
+ // and thus be Undefined Behavior!
118
+ let f1_ptr = unsafe { ptr :: addr_of_mut! ((* uninit . as_mut_ptr ()). field) };
119
+ unsafe { f1_ptr . write (true ); }
120
+ let init = unsafe { uninit . assume_init () };
121
+ ```
122
+
123
+
73
124
## The dereference operator
74
125
75
126
> ** <sup >Syntax</sup >** \
@@ -494,6 +545,7 @@ See [this test] for an example of using this dependency.
494
545
[ float-float ] : https://github.com/rust-lang/rust/issues/15536
495
546
[ Function pointer ] : ../types/function-pointer.md
496
547
[ Function item ] : ../types/function-item.md
548
+ [ undefined behavior ] : ../behavior-considered-undefined.md
497
549
498
550
[ _BorrowExpression_ ] : #borrow-operators
499
551
[ _DereferenceExpression_ ] : #the-dereference-operator
0 commit comments