Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Rust compiler give an uninitialized variable error when initializing an array in a loop?

Tags:

rust

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`
like image 279
Muffo Avatar asked Mar 06 '23 00:03

Muffo


1 Answers

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)
    }
}
like image 165
Boiethios Avatar answered Apr 12 '23 23:04

Boiethios