gpt4 book ai didi

Rustc 仅在分配溢出的值时发出警告

转载 作者:行者123 更新时间:2023-11-29 07:51:26 26 4
gpt4 key购买 nike

我发现我认为这是一种非常奇怪的行为。当变量在运行时溢出时,Rustc 会崩溃;这对我来说很有意义。但是,它只会在编译时分配溢出的值时发出警告。那不应该是编译时错误吗?否则,两种行为似乎不一致。

我预计会出现编译时错误:

fn main() {
let b: i32 = 3_000_000_000;
println!("{}", b);
}

产生:

<anon>:2:18: 2:31 warning: literal out of range for i32, #[warn(overflowing_literals)] on by default
<anon>:2 let b: i32 = 3_000_000_000;

Playground 1

这对我来说很有意义:

fn main() {
let b: i32 = 30_000;
let c: i32 = 100_000;
let d = b * c;
println!("{}", d);
}

产生:

thread '<main>' panicked at 'arithmetic operation overflowed', <anon>:4
playpen: application terminated with error code 101

Playground 2

编辑:

鉴于 FrancisGagné 的评论,我发现 Rust 实现了在操作期间检查溢出的运算符,例如 checked_mul ,我看到需要自己实现溢出检查。这是有道理的,因为应该优化发布版本,并且不断检查溢出可能会变得昂贵。所以我不再看到“不一致”。但是,我仍然感到惊讶,分配一个会溢出的值不会导致编译时错误。在 golang 中它将是:Go Playground

最佳答案

实际上,您的评论与您观察到的行为不一致:

  • 在你的第一个例子中:你得到一个编译时警告,你忽略了它,因此编译器推断你想要包装行为
  • 在你的第二个例子中:你得到一个运行时错误

Go 示例类似于第一个 Rust 示例(除了 Go 在设计上没有警告)。


在 Rust 中,下溢或上溢会导致一个未指定的值,它可以是 ! 或计算机科学中的 bottom,一个特殊的值表示控制流发散,这通常意味着流产或异常。

此规范允许:

  • 检测 Debug模式以在溢出发生的那一刻捕获所有溢出
  • 不检测1 Release 模式(并在那里使用包装算法)

而且两种模式都符合规范。

1 默认情况下不进行检测,如果您选择并在繁重的数字代码之外以相对适中的性能成本使用简单标志激活 Release 中的溢出检查,则可以。


关于溢出检查的代价:目前Rust/LLVM的情况对调试有帮助,但并没有真正优化。因此,在这个框架中,溢出检查成本。如果情况有所改善,那么 rustc 可能有一天会决定在 Release 中默认激活溢出检查。

Midori (用类似C#的语言开发的微软实验性操作系统),即使在Release builds中也开启了溢出检查:

In Midori, we compiled with overflow checking on by default. This is different from stock C#, where you must explicitly pass the /checked flag for this behavior. In our experience, the number of surprising overflows that were caught, and unintended, was well worth the inconvenience and cost. But it did mean that our compiler needed to get really good at understanding how to eliminate unnecessary ones.

显然,他们改进了编译器,以便:

  • 它会推理变量的范围,并在可能的情况下静态地消除边界检查和溢出检查
  • 它会尽可能多地聚合检查(对多个可能溢出的操作进行一次检查)

后者只在 Release 中完成(你失去了精度)但减少了分支的数量。

那么,剩下的成本是多少?

可能妨碍优化的不同算术规则:

  • 在正则算术中,64 + x - 128 可以优化为 x - 64;激活溢出检查后,编译器可能无法执行此优化
  • 如果编译器没有内置溢出检查向量,向量化也会受到阻碍
  • ...

不过,除非代码是大量数字(例如科学模拟或图形),否则它可能确实会影响它。

关于Rustc 仅在分配溢出的值时发出警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35182474/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com