Is initializing code restrained to type of receiver variable?

The code:

let myvar: u8 = 2<<8 - 1;
println!("myvar={}", myvar);
outputs:
myvar=0

This might be caused because 2<<8 is too big for the receiver.
But if so, why? I thought that the RESULT of the initializing code must be in the bounds of the receiving type?

- takes precedence over <<, thus that will be interpreted as 2<<7, which in the lower 8 bits is 0
you probably meant

fn main() {
    let myvar: u8 = (1<<8) - 1;
    println!("myvar={}", myvar);
}

which fails with an error at least:

error: attempt to shift left with overflow

(2<<7 is ok? yes, apparently it only looks at the shift value is smaller than 8, not that the shifted value overflows!)

1 Like

Rust never casts between integer types implicitly. If you want to perform a calculation using one type and then cast the result to another type, you must include an explicit cast. For example:

let myvar: u8 = ((2u16 << 8) - 1) as u8;
1 Like

Exactly! I mistakenly thought of 2 to the power of x and used x for shifting which is obviously wrong and (1<<8) -1 is indeed the right way to do this. Thx!

Also, this precedence trips me up; didn't expect this.
Would be good is Rust (as Ada would complain about not using parenthesis in such cases!

Thx! That is good info. I'm just starting out :slight_smile:

Also, note that if your purpose is to get the greatest u8, you can do so by calling u8::max_value().

let x = u8::max_value();
println!("{}", x); // => 255
2 Likes

yes, it's a bit of a gotcha, wouldn't mind the compiler suggesting explicit parenthesis in this kind of cases

Or maybe clippy instead of the compiler