Hacker News new | ask | show | jobs
by rockmeamedee 2168 days ago
The post says

  The new API to cast in an unsafe manner is:

  let x: f32 = 1.0;
  let y: u8 = unsafe { x.to_int_unchecked() };

  But as always, you should only use this method as a last resort. Just like with array access, the compiler can often optimize the checks away, making the safe and unsafe versions equivalent when the compiler can prove it.
I believe for array access you can elide the bounds checking with an assert like

  assert!(len(arr) <= 255)
  let mut sum = 0;
  for i in 0..255 {
    sum += arr[i];//this access doesn't emit bounds checks in the compiled code
  }
I'm guessing it would work like this with casts?

  assert!(x <= 255. && x >= 0);
  let y: u8 = x as u8; // no check
2 comments

Interestingly enough, it looks like that does not in fact change how the check works https://godbolt.org/z/rdxrh1

Here's an example of how when it can detect it, it does the right thing: https://godbolt.org/z/hPqf69

I am not an expert in these hints, maybe someone else knows!

It should be `assert!(len(arr) >= 255)` (greater instead of less than), right?
If you want to omit a bounds check, the compiler needs to know that the length of the array covers the upper bound of the loop, right?
If the array length is known to be strictly less than 255 then there is definitely an out-of-bounds access inside the loop, but since this is a panic rather than undefined behavior it could matter how many loop iterations are executed before the out of bounds access occurs, so the check can't be omitted.

If the array size is definitely greater than or equal to 255 then all the array accesses in the loop will be in bounds and no further bounds check is required.

Oh, right.
Assuming a unsigned byte, that range of values is between 0 and 255 inclusive, so `len(arr) <= 255` is correct.
But the loop goes up to 255. So if len(arr) == 10, then assert!(len(arr) <= 255) woulds succeed, but you'd get an out-of-bounds access if you tried to access arr at 11.
actually >, not >=
len(arr) == 255 should be okay, 0..255 doesn't include the end index[0]. In the Rust playground[1] I see it only print up to 254.

[0] https://doc.rust-lang.org/stable/rust-by-example/flow_contro... [1] https://play.rust-lang.org/?version=stable&mode=debug&editio...