golang slice 编译器 边界检测?

2018-07-17 20:09:52 +08:00
 helloworld12

https://github.com/golang/go/blob/b59b42cee8c1ca209dafd952da872fd493b77405/src/encoding/binary/binary.go#L51-L54

看里面的代码是说

_ = b[1]

可以用来,让编译器,进行边界检测

但是:

https://play.golang.org/p/SHG6bYjnw8_z

这个是可以运行的,报错也是运行时报错?

panic: runtime error: index out of range

goroutine 1 [running]:
main.main()
    /tmp/sandbox468585689/main.go:9 +0x20
1747 次点击
所在节点    问与答
5 条回复
lujjjh
2018-07-17 21:06:55 +08:00
应该是为了减少运行时的 bounds check 的:

uint16(b[0]) | uint16(b[1])<<8 会生成两条 bounds checks,但是如果先写一个 _ = b[1] 就可以减少一次( b[1] 检查过之后 b[0] 就不用检查了)。
helloworld12
2018-07-18 00:34:56 +08:00
@lujjjh 减少边界检测?不是直接取值吗? 边界检测有什么用, 不是超出范围就崩溃吗?
lujjjh
2018-07-18 08:51:34 +08:00
@helloworld12 之所以能抛出超出范围的 panic,就是因为边界检测的存在。编译器在编译的时候插入边界检测的指令,运行时进行边界检测。并不是像你理解的那样在编译期间做边界检测。

所谓的 bounds check hint to compiler 是提示编译器这里可以优化成只插入一次边界检测,直接检测 b[1] 有没有越界。

编译成汇编代码应该可以看出区别。
helloworld12
2018-07-18 09:02:58 +08:00
谢谢
reus
2018-07-18 11:57:17 +08:00
不用看这个,有个 commit 会改进 bounds check elimination,这个会回滚的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/471750

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX