Search code examples
performanceexceptionrustdivide-by-zero

Can I disable checking for zero division every time the division happens?


In order to better understand Rusts panic/exception mechanisms, I wrote the following piece of code:

#![feature(libc)]

extern crate libc;

fn main() {
    let mut x: i32;
    unsafe {
      x = libc::getchar();
    }

    let y = x - 65;
    println!("{}", x);

    let z = 1 / y;
    println!("{}", z);
}

I wanted to check how Rust deals with division by zero cases. Originally I assumed it was either taking an unhandled SIGFPE to the face and dying or it implemented a handler and rerouted it to a panic (which can be dealt with nowadays?).

The code is verbose because I wanted to make sure that Rust does not do anything "smart" when it knows at compile-time that something is zero, hence the user input. Just give it an 'A' and it should do the trick.

I found out that Rust actually produces code that checks for zero division every time before the division happens. I even looked at the assembly for once. :-)

Long story short: Can I disable this behaviour? I imagine for larger datasets this can have quite a performance impact. Why not use our CPUs ability to detect this stuff for us? Can I set up my own signal handler and deal with the SIGFPE instead?

According to an issue on Github the situation must have been different some time ago.

I think checking every division beforehand is far away from "zero-cost". What do you think? Am I missing something obvious?


Solution

  • Long story short: Can I disable this behaviour?

    Yes you can: std::intrinsics::unchecked_div(a, b). Your question also applies to remainder (thats how Rust calls modulo): std::intrinsics::unchecked_rem(a, b). I checked the assembly output here to compare it to C++.

    In the documentation it states:

    This is a nightly-only experimental API. (core_intrinsics)

    intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library

    So you have to use the nightly build and it is unlikely to ever come in a stabilized form to the standard library for the reasons Matthieu M. already pointed out.