impala icon indicating copy to clipboard operation
impala copied to clipboard

Constant expression for smallest i32 emits undef

Open ergawy opened this issue 7 years ago • 2 comments

The following code:

extern "C" {
    fn print_int(i32) -> ();
}

fn main() -> i32 {
    let test : i32 = 1 << 31;
    print_int(test);

    0
}

emits test value as undef while it should be the smallest i32 value.

ergawy avatar Oct 05 '16 14:10 ergawy

Currently, we follow the C-standard in terms of what is considered undefined and what not. The C-Standard says to E1 << E2:

If E1 has a signed type and nonnegative value, and E1 × 2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

But 2^31 is not representable in i32, hence the behavior is undefined and the behavior of the compiler is correct.

However, that being said, I checked what clang does. Doing things like 1 << 31 seems to be such a common pattern that clang has the mercy to simply do what you would expect. We have three options:

  1. Stick to the C-Standard and leave everything as it is.
  2. Do what clang (and others) are doing.
  3. Do sth completely different.

After discussion with Richard we are likely doing option 2). In the long run, however, I'd like bake this into the type system...

leissa avatar Oct 06 '16 16:10 leissa

For the moment, we decided for option 2, but in the long run we would like to track the wrap-around property in the type.

richardmembarth avatar Oct 13 '16 12:10 richardmembarth