I'm trying to iterate over all possible byte (u8
) values. Unfortunately my range literals in 0..256
are cast to u8
and 256
overflows:
fn foo(byte: u8) {
println!("{}", byte);
}
fn main() {
for byte in 0..256 {
foo(byte);
println!("Never executed.");
}
for byte in 0..1 {
foo(byte);
println!("Executed once.");
}
}
The above compiles with:
warning: literal out of range for u8
--> src/main.rs:6:20
|
6 | for byte in 0..256 {
| ^^^
|
= note: #[warn(overflowing_literals)] on by default
The first loop body is never executed at all.
My workaround is very ugly and feels brittle because of the cast:
for short in 0..256 {
let _explicit_type: u16 = short;
foo(short as u8);
}
Is there a better way?
This is issue Unable to create a range with max value.
The gist of it is that
byte
is inferred to beu8
, and therefore0..256
is represented as aRange<u8>
but unfortunately256
overflows as anu8
.The current work-around is to use a larger integral type and cast to
u8
later on since256
is actually never reached.There is a RFC for inclusive range with
...
which has entered final comment period; maybe in the future it'll be possible to havefor byte in 0...255
or its alternative(0..255).inclusive()
.As of Rust 1.26, inclusive ranges are stabilized using the syntax
..=
, so you can write this as: