A chain of proven arithmetic operations in Rust

When performing integer arithmetic with overflow checks, calculations often have to compose a few arithmetic operations. The direct way to bind proven arithmetic in Rust uses methods checked_*and Optionchaining:

fn calculate_size(elem_size: usize,
                  length: usize,
                  offset: usize)
                  -> Option<usize> {
    elem_size.checked_mul(length)
             .and_then(|acc| acc.checked_add(offset))
}

However, this tells the compiler to create a branch for each elementary operation. I came across a more detailed approach using methods overflowing_*:

fn calculate_size(elem_size: usize,
                  length: usize,
                  offset: usize)
                  -> Option<usize> {
    let (acc, oflo1) = elem_size.overflowing_mul(length);
    let (acc, oflo2) = acc.overflowing_add(offset);
    if oflo1 | oflo2 {
        None
    } else {
        Some(acc)
    }
}

, ( , overflowing_* ). .

- , Rust , , , ?

+4
1

- , Rust , , , ?

, , LLVM : "LLVM IR" "ASM" "Run", #[inline(never)] , , , , . :

use std::env;

#[inline(never)]
fn calculate_size(elem_size: usize,
                  length: usize,
                  offset: usize)
                  -> Option<usize> {
    let (acc, oflo1) = elem_size.overflowing_mul(length);
    let (acc, oflo2) = acc.overflowing_add(offset);
    if oflo1 | oflo2 {
        None
    } else {
        Some(acc)
    }
}

fn main() {
    let vec: Vec<usize> = env::args().map(|s| s.parse().unwrap()).collect();
    let result = calculate_size(vec[0], vec[1], vec[2]);
    println!("{:?}",result);
}

, , , , Rust LLVM , , . , , , LLVM .

; .

: , Release.

+4

All Articles