Nobuki Katori
Nobuki Katori

Reputation: 63

Is the out-of-bound array indexing supposed to produce an error or warning in Rust?

I'm reading The Rust book and I run across this example:

fn main() {
    let a = [1, 2, 3, 4, 5];
    let index = 10;

    let element = a[index];

    println!("The value of element is: {}", element);
}

And in the book it says that after running cargo run...

The compilation didn’t produce any errors, but the program resulted in a runtime error and didn’t exit successfully.

I don't understand this. I see a compilation error, and even when I compile via cargo build or rustc src/main.rs I also see the error.

What do they mean in this example? Why is that not a compilation error, but rather a runtime one?

Upvotes: 5

Views: 2593

Answers (2)

Angelicos Phosphoros
Angelicos Phosphoros

Reputation: 3057

Compiler is smarter now than it was so it produces compile error.

You need to change code to be less easy to validate for compiler. For example:

fn main() {
    let a = [1, 2, 3, 4, 5];
    let index = a.len() + 1;

    let element = a[index];

    println!("The value of element is: {}", element);
}

Code above compiles and panics at current version (1.60).

Also, generally compiler can prove bounds access only for arrays ([T; N]) but not slices and Vecs.

Upvotes: 2

Ibraheem Ahmed
Ibraheem Ahmed

Reputation: 13518

Rust got smarter constant evaluation since the book was written. There is an open pull request that updates the chapter to the following:

What happens if you try to access an element of an array that is past the end of the array? If you change the example to the following code, it will not compile:

fn main() {
    let a = [1, 2, 3, 4, 5];
    let index = 10;

    let element = a[index];

    println!("The value of element is: {}", element);
}

Building this code using cargo build produces the following result:

$ cargo run
   Compiling arrays v0.1.0 (file:///projects/arrays)
error: this operation will panic at runtime
 --> src/main.rs:5:19
  |
5 |     let element = a[index];
  |                   ^^^^^^^^ index out of bounds: the len is 5 but the index is 10
  |
  = note: `#[deny(unconditional_panic)]` on by default

error: aborting due to previous error

error: could not compile `arrays`.

To learn more, run the command again with --verbose.

When the compiler can prove that invalid array access occurs, it will fail to compile. However, there are some cases where the compilation won't produce any errors, but the program itself will fail with a runtime error and won't exit successfully.

At runtime, when you attempt to access an element using indexing, Rust will check that the index you’ve specified is less than the array length. If the index is greater than or equal to the array length, Rust will panic.

This is the first example of Rust’s safety principles in action. In many low-level languages, this kind of check is not done, and when you provide an incorrect index, invalid memory can be accessed. Rust protects you against this kind of error by not allowing the program to compile, or it might panic at runtime if the error could not be identified at compile-time, which would immediately exit the program instead of allowing the invalid memory access to occur. Chapter 9 discusses more of Rust’s error handling.

Upvotes: 1

Related Questions