From 79bafdc6be70eaf452ff9bcce7dde00806f28018 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Tue, 12 Jan 2021 21:25:57 -0500 Subject: [PATCH] Fixes #2417. Get the index from user input instead of a const. The compiler has gotten sufficiently smart regarding const evaluation to catch many trivial instances of array-index-out-of-bounds at compile time. However, the compiler can't read peoples' minds... yet. --- .../output.txt | 15 ----------- .../src/main.rs | 21 +++++++++++++-- src/ch03-02-data-types.md | 27 ++++++++++++++----- 3 files changed, 39 insertions(+), 24 deletions(-) delete mode 100644 listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt diff --git a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt deleted file mode 100644 index a4dd90c0bd..0000000000 --- a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ 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 length 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. diff --git a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs index 5ce0ed4a5b..5e5121684d 100644 --- a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs @@ -1,8 +1,25 @@ +use std::io; + fn main() { let a = [1, 2, 3, 4, 5]; - let index = 10; + + println!("Please enter an array index."); + + let mut index = String::new(); + + io::stdin() + .read_line(&mut index) + .expect("Failed to read line"); + + let index: usize = index + .trim() + .parse() + .expect("Index entered was not a number"); let element = a[index]; - println!("The value of element is: {}", element); + println!( + "The value of the element at index {} is: {}", + index, element + ); } diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index 85063f71cd..1b93f7892e 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -324,8 +324,8 @@ get the value `2` from index `[1]` in the array. ##### Invalid Array Element Access What happens if you try to access an element of an array that is past the end -of the array? Say you change the example to the following code, which will -compile but exit with an error when it runs: +of the array? Say you change the example to the following, which uses code +similar to the guessing game in Chapter 2 to get an array index from the user: Filename: src/main.rs @@ -333,17 +333,30 @@ compile but exit with an error when it runs: {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs}} ``` -Running this code using `cargo run` produces the following result: +This code compiles successfully. If you run this code using `cargo run` and +enter 0, 1, 2, 3, or 4, the program will print out the corresponding value at +that index in the array. If you instead enter a number past the end of the +array, such as 10, you'll see output like this: + + ```console -{{#include ../listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt}} +thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 10', src/main.rs:19:19 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` -The compilation didn’t produce any errors, but the program resulted in a -*runtime* error and didn’t exit successfully. When you attempt to access an +The program resulted in a *runtime* error at the point of using an invalid +value in the indexing operation. The program exited at that point with an error +message and didn't execute the final `println!`. 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. +length, Rust will panic. This check has to happen at runtime, especially in +this case, because the compiler can't possibly know what the value a user +running the code will later enter. 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