Skip to content

Rust -- Integer Overflow

Rust has a brilliant way to give the developer control over integer overflow...
Let's have look

Integer overflow occurs when one tries to set a value that is higher than the highest accepted value of an integer.

OVERFLOW!

For instance, an u8, which is a unsigned 8-bit long integer accepts a value between 0 & 255
When trying to set its value to 256 or higher, one gets an integer overflow

Note

Integer overflow includes what is called integer underflow when reaching the lower limits.

AFAIK, most languages do not come packed with native methods to deal with integer overflow.
Even in so-called advanced languages like Java and GoLang, one has to use very hacky code to detect and handle these.

In Rust, there are two possible reactions:

  • when compiling in debug mode, the compiler will panic about integer overflow
  • when compiling in --release mode, there are no checks for integer overflow and rust will use complement wrapping (ie 256 becomes 0, 257 becomes 1 etc., just like it would happen in Java or Go)

BUT there are methods to avoid this default behavior in release mode:

  • wrapping_* methods make the wrapping explicit
      // for instance
      let x:u8 = 255;
      let y:u8 = 2;
      let z = x.wrapping_add(y); // will be 1
    
  • checked_* methods will return None when integer overflow
      // for instance
      let x:u8 = 255;
      let y:u8 = 2;
      let z = match x.checked_add(y) {
          Some(num) => num,
          None => panic!("You overflowed baby !")
      };  // checked_* methods will return None on overflow 
          // and the value if everything is ok
    
  • overflowing_* methods will return a tuple(Self, bool) with the integer, eventually overflown and a boolean that indicates whether there has been integer overflow
      let x:u8 = 255;
      let y:u8 = 2;
      let z = x.overflowing_add(y);
      if(z.1) {
          panic!("You overflowed baby !");
      }
      let z = z.0;
    
  • saturating_* methods will prevent the overflow by either not going higher than the MAX or lower than the MIN
    let x:u8 = 255;
    let y:u8 = 2;
    let z = x.saturating_add(y); // will return 255 as that is the MAX value of an u8
    

Strangely enough... overflow appears not to be dealt with for floats and other numeric values...

Comments