小编mza*_*uev的帖子

在 Rust 中链接检查算术运算

在执行带有溢出检查的整数算术时,计算通常需要组合多个算术运算。在 Rust 中链接检查算术的一种直接方法是使用checked_*方法和Option链接:

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

但是,这告诉编译器为每个基本操作生成一个分支。我遇到了一种使用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)
    }
}
Run Code Online (Sandbox Code Playgroud)

不考虑溢出而继续计算并使用按位 OR 聚合溢出标志可确保在整个评估中最多执行一个分支(前提是overflowing_*生成无分支代码的实现)。这种优化友好的方法更麻烦,并且在处理中间值时需要谨慎。

有没有人有过 Rust 编译器如何在各种 CPU 架构上优化上述任一模式的经验,以判断显式展开是否值得,尤其是对于更复杂的表达式?

integer-overflow rust integer-arithmetic

5
推荐指数
1
解决办法
760
查看次数