Skip to content

Commit e4042e6

Browse files
authored
Merge pull request #130 from vorner/uninit-improvements
Various unchecked-uninit improvements
2 parents 0a8c3a4 + 7b6cc4f commit e4042e6

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

src/unchecked-uninit.md

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ Unfortunately this is pretty rigid, especially if you need to initialize your
88
array in a more incremental or dynamic way.
99

1010
Unsafe Rust gives us a powerful tool to handle this problem:
11-
`mem::uninitialized`. This function pretends to return a value when really
12-
it does nothing at all. Using it, we can convince Rust that we have initialized
13-
a variable, allowing us to do trickier things with conditional and incremental
14-
initialization.
11+
[`mem::uninitialized`][uninitialized]. This function pretends to return a value
12+
when really it does nothing at all. Using it, we can convince Rust that we have
13+
initialized a variable, allowing us to do trickier things with conditional and
14+
incremental initialization.
1515

1616
Unfortunately, this opens us up to all kinds of problems. Assignment has a
1717
different meaning to Rust based on whether it believes that a variable is
@@ -24,9 +24,9 @@ longer safely use normal assignment.
2424
This is also a problem if you're working with a raw system allocator, which
2525
returns a pointer to uninitialized memory.
2626

27-
To handle this, we must use the `ptr` module. In particular, it provides
27+
To handle this, we must use the [`ptr`] module. In particular, it provides
2828
three functions that allow us to assign bytes to a location in memory without
29-
dropping the old value: `write`, `copy`, and `copy_nonoverlapping`.
29+
dropping the old value: [`write`], [`copy`], and [`copy_nonoverlapping`].
3030

3131
* `ptr::write(ptr, val)` takes a `val` and moves it into the address pointed
3232
to by `ptr`.
@@ -56,13 +56,13 @@ const SIZE: usize = 10;
5656
let mut x: [Box<u32>; SIZE];
5757

5858
unsafe {
59-
// convince Rust that x is Totally Initialized
60-
x = mem::uninitialized();
61-
for i in 0..SIZE {
62-
// very carefully overwrite each index without reading it
63-
// NOTE: exception safety is not a concern; Box can't panic
64-
ptr::write(&mut x[i], Box::new(i as u32));
65-
}
59+
// convince Rust that x is Totally Initialized
60+
x = mem::uninitialized();
61+
for i in 0..SIZE {
62+
// very carefully overwrite each index without reading it
63+
// NOTE: exception safety is not a concern; Box can't panic
64+
ptr::write(&mut x[i], Box::new(i as u32));
65+
}
6666
}
6767

6868
println!("{:?}", x);
@@ -80,6 +80,19 @@ Every control path through that variable's scope must initialize the value
8080
before it ends, if it has a destructor.
8181
*[This includes code panicking](unwinding.html)*.
8282

83+
Not being careful about uninitialized memory often leads to bugs and it has been
84+
decided the [`mem::uninitialized`][uninitialized] function should be deprecated.
85+
The [`MaybeUninit`] type is supposed to replace it as its API wraps many common
86+
operations needed to be done around initialized memory. This is nightly only for
87+
now.
88+
8389
And that's about it for working with uninitialized memory! Basically nothing
8490
anywhere expects to be handed uninitialized memory, so if you're going to pass
8591
it around at all, be sure to be *really* careful.
92+
93+
[uninitialized]: ../std/mem/fn.uninitialized.html
94+
[`ptr`]: ../std/ptr/index.html
95+
[`write`]: ../std/ptr/fn.write.html
96+
[`copy`]: ../std/ptr/fn.copy.html
97+
[`copy_nonoverlapping`]: ../std/ptr/fn/copy_nonoverlapping.html
98+
[`MaybeUninit`]: ../std/mem/union.MaybeUninit.html

0 commit comments

Comments
 (0)