Checked Uninitialized Memory
Like C, all stack variables in Rust are uninitialized until a value is explicitly assigned to them. Unlike C, Rust statically prevents you from ever reading them until you do:
|
3 | println!("{}", x);
| ^ use of possibly uninitialized `x`
This is based off of a basic branch analysis: every branch must assign a value
to x before it is first used. For short, we also say that "x is init" or
"x is uninit".
Interestingly, Rust doesn't require the variable to be mutable to perform a delayed initialization if every branch assigns exactly once. However the analysis does not take advantage of constant analysis or anything like that. So this compiles:
but this doesn't:
|
6 | println!("{}", x);
| ^ use of possibly uninitialized `x`
while this does:
Of course, while the analysis doesn't consider actual values, it does have a relatively sophisticated understanding of dependencies and control flow. For instance, this works:
let x: i32;
loop
// It also knows that it's impossible to get here without reaching the break.
// And therefore that `x` must be initialized here!
println!;
If a value is moved out of a variable, that variable becomes logically uninitialized if the type of the value isn't Copy. That is:
However reassigning y in this example would require y to be marked as
mutable, as a Safe Rust program could observe that the value of y changed:
Otherwise it's like y is a brand new variable.