Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it expected that a too large bitshift is undefined behavior in Rust?

When you run this code:

#![allow(exceeding_bitshifts)]

fn main() {
    const NUMBER: u64 = 0b_10101010;

    fn print_shift(i: u32) {
        println!("{:b}", NUMBER >> i);
    }

    print_shift(65);
    println!("{:b}", NUMBER >> 65);
}

You see that shifting the bits of a number with a value that exceed the bit length produces different behavior when doing at compile time or runtime.

Is it a normal behavior? Is it documented somewhere? This is not in the list of documented undefined behavior.

like image 859
Boiethios Avatar asked Oct 12 '17 16:10

Boiethios


1 Answers

No, this is not expected, but it is not undefined behavior. This is "just" a bug.

There should be no difference between how the constant is computed at compile time and how the value is computed at runtime. This is a hard problem in general as the machine performing the compilation and the machine running the code might have completely different architectures.


When talking about debug vs release builds, the behavior of "too large" bitshifts is expected, and is also not undefined behavior. The clue is in the error message:

attempt to shift right with overflow

Integer overflow is neither unsafe nor undefined:

The Rust compiler does not consider the following behaviors unsafe, though a programmer may (should) find them undesirable, unexpected, or erroneous.

  • ...
  • Integer overflow

See also:

  • How can integer overflow protection be turned off?
like image 101
Shepmaster Avatar answered Nov 15 '22 09:11

Shepmaster