6

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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Perseids
  • 12,584
  • 5
  • 40
  • 64
  • 1
    For starters, you can lose `explicitType` and write `for i in 0..256`, as long as you cast in `foo(i as u8)`. Then `i` will be of type `i32`. That's only marginally better though. –  Aug 30 '15 at 12:15
  • @delnan: Your tip has brought me to `(0..256).map(|byte| byte as u8)`, which is just as unintuitive, but at least points out the magic to the reader. And it's still not good :( – Perseids Aug 30 '15 at 12:22

2 Answers2

9

As of Rust 1.26, inclusive ranges are stabilized using the syntax ..=, so you can write this as:

for byte in 0..=255 {
    foo(byte);
}
porglezomp
  • 1,333
  • 12
  • 24
5

This is issue Unable to create a range with max value.

The gist of it is that byte is inferred to be u8, and therefore 0..256 is represented as a Range<u8> but unfortunately 256 overflows as an u8.

The current work-around is to use a larger integral type and cast to u8 later on since 256 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 have for byte in 0...255 or its alternative (0..255).inclusive().

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 1
    Right now there is open [pull-request](https://github.com/rust-lang/rust/pull/30884) implementing this feature. – incrop Feb 20 '16 at 11:47