5

The compiler complains a variable is not initialized, and it is right. However, the variable appears on the left side of the expression.

I guess I could easily fix this by initializing the array, but I am more interested in understanding why the compiler thinks this is an error condition.

I don't think this would be flagged as an error in other languages.

Here is my code:

fn main() {
    const LEN: usize = 5;
    let mut arr: [u32; LEN];

    for i in 0..LEN {
        arr[i] = fib(i as u32);
    }

    println!("{:?}", arr);
}

fn fib(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fib(n - 1) + fib(n - 2),
    }
}

Here is the error:

error[E0381]: use of possibly uninitialized variable: `arr`
 --> src/main.rs:6:9
  |
6 |         arr[i] = fib(i as u32);
  |         ^^^^^^^^^^^^^^^^^^^^^^ use of possibly uninitialized `arr`

error[E0381]: use of possibly uninitialized variable: `arr`
 --> src/main.rs:9:22
  |
9 |     println!("{:?}", arr);
  |                      ^^^ use of possibly uninitialized `arr`
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Muffo
  • 1,733
  • 2
  • 19
  • 29
  • 1
    The compiler isn't smart enough, however Rust give a lot of tool to make better code than this Iterator is the way to go or std::mem::uninitialized if you want keep an array is the "trust me" solution. – Stargateur Nov 25 '18 at 22:24
  • Thanks for pointing out std::mem::uninitialized. A quick search brought me to this page that shows some code very similar to mine: https://doc.rust-lang.org/std/mem/fn.uninitialized.html – Muffo Nov 26 '18 at 02:42
  • 1
    See also [What is the proper way to initialize a fixed length array?](https://stackoverflow.com/q/31360993/155423); [Initialize array holding struct more efficiently](https://stackoverflow.com/q/44182269/155423); [Is there a way to not have to initialize arrays twice?](https://stackoverflow.com/q/26185618/155423). – Shepmaster Nov 26 '18 at 13:42

1 Answers1

7

When you do a for loop, the code is sequential: the compiler first set the value at index 0, then 1, etc. but it has no clue that you are initializing the array that way. You could, for example, forgot the last index, and your code would be invalid.

To say it simply: you can modify a variable only when it was initialized, and arr is your variable, not arr[0].

When you index something in Rust, this is desugared into the index_mut method. In your situation, you are calling a method of arr that is an uninitialized variable.


As you said, the solution to your issue is to initialize your array first, with zeroes for example:

fn main() {
    const LEN : usize = 5;
    let mut arr = [0; LEN];

    for i in 0..LEN {
        arr[i] = fib(i as u32);
    }

    println!("{:?}", arr);
}


fn fib(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fib(n-1) + fib(n-2)
    }
}
Boiethios
  • 38,438
  • 19
  • 134
  • 183