【问题标题】:Is it expected that a too large bitshift is undefined behavior in Rust?是否预计过大的位移在 Rust 中是未定义的行为?
【发布时间】:2017-10-13 00:47:54
【问题描述】:

当你运行这段代码时:

#![allow(exceeding_bitshifts)]

fn main() {
    const NUMBER: u64 = 0b_10101010;

    fn print_shift(i: u32) {
        println!("{:b}", NUMBER >> i);
    }

    print_shift(65);
    println!("{:b}", NUMBER >> 65);
}

您会看到,在编译时或运行时移动具有超过位长度的值的数字的位会产生不同的行为。

这是正常行为吗?它是否记录在某处?这不在list of documented undefined behavior 中。

【问题讨论】:

    标签: rust undefined-behavior bit-shift


    【解决方案1】:

    不,这是预期的,但它不是未定义的行为This is "just" a bug.

    应该在编译时如何计算常量与在运行时如何计算值之间没有区别。这通常是一个难题,因为执行编译的机器和运行代码的机器可能具有完全不同的架构。


    在谈论调试与发布构建时,“太大”的位移行为是意料之中的,而且也是不是未定义的行为。线索在错误信息中:

    尝试通过溢出右移

    Integer overflow is neither unsafe nor undefined:

    Rust 编译器不认为以下行为是不安全的, 尽管程序员可能(应该)发现它们不受欢迎、出乎意料或 错误的。

    • ...
    • 整数溢出

    另见:

    【讨论】:

    • 同一个函数,同一个参数(x.shr(y))在不同的调用中给出不同的答案。这不是UB吗?
    • @Boiethios 我不确定您是否正确使用了术语未定义的行为random()(通常)在不同的调用中返回不同的答案,但这并不意味着它的行为是不确定的。
    • 不,UB 专门指规范未定义行为的情况,现代 C/C++ 编译器越来越多地将其视为一种优化操作,当有人绊倒其中一个时会导致更加混乱的结果许多 C/C++ 中未定义行为的案例。
    • 另一方面,Rust 非常努力地避免未定义的行为,并且在无法避免的情况下(某些与指针相关的操作本质上是不安全的),需要程序员明确地通过“不安全”块来确认这一点。
    猜你喜欢
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    相关资源
    最近更新 更多