为了账号安全,请及时绑定邮箱和手机立即绑定

Go 允许算术运算溢出而不是抛出异常是预期的行为吗?

Go 允许算术运算溢出而不是抛出异常是预期的行为吗?

Go
江户川乱折腾 2023-06-19 17:02:28
我正在将一些 Go 代码移植到 Rust,我意识到当乘法期间发生溢出时 Rust 会恐慌,而 Go 允许发生溢出。下面的测试代码,不会导致溢出但会打印减少的值。(通过:https: //play.golang.org/测试)func main() {    fmt.Println("test\n")    var key uint64 = 15000;    key = key*2862933555777941757 + 1    fmt.Println(key)}
查看完整描述

1 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

规范:整数溢出:

对于无符号整数值,操作 +、-、* 和 << 计算模 2 n,其中n是无符号整数类型的位宽。粗略地说,这些无符号整数运算在溢出时丢弃高位,程序可能依赖于“环绕”

对于有符号整数,操作 +、-、*、/ 和 << 可能会合法溢出,并且结果值存在并且由有符号整数表示、操作及其操作数确定地定义。溢出不会导致运行时恐慌。假设不会发生溢出,编译器可能不会优化代码。例如,它可能不会假设这x < x + 1总是正确的。

如上所述,存在溢出并且不会导致运行时恐慌。

但必须小心,就好像你有一个常量表达式,因为它们具有任意精度,如果要将结果转换为不适合目标类型有效范围的固定精度,则会导致编译时间 -错误。

例如:

const maxuint64 = 0xffffffffffffffff

var key uint64 = maxuint64 * maxuint64


fmt.Println(key)

以上产量:


constant 340282366920938463426481119284349108225 overflows uint64

maxuint64 * maxuint64是一个计算正确的常量表达式(它的值为340282366920938463426481119284349108225),但是当这个值被赋值给keytype 的变量uint64时,它会导致编译时错误,因为这个值不能用 type 的值表示uint64。但这不是运行时恐慌。


查看完整回答
反对 回复 2023-06-19
  • 1 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信