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

为什么在 unsafe.Sizeof() 中取消引用 nil 指针不会导致恐慌?

为什么在 unsafe.Sizeof() 中取消引用 nil 指针不会导致恐慌?

Go
慕桂英4014372 2022-11-08 15:11:10
https://go.dev/play/p/X_BH4qGgXHJpackage mainimport (    "fmt"    "unsafe")func main() {    var i *int    fmt.Println(unsafe.Sizeof(*i)) // dereference of null pointer i}为什么这段代码没有unsafe.Sizeof(*i)导致运行时恐慌?
查看完整描述

1 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

规格:包装不安全:

Alignof对、Offsetof和的调用Sizeof是类型的编译时常量表达式uintptr

这些函数在编译时进行评估,在运行时不会发生实际的取消引用。

这是可能的,因为不需要指向的值,只需要有关其类型的信息,不需要取消引用。

它也记录在unsafe.Sizeof()

Sizeof 的返回值是一个 Go 常量。

Go 中的常量是编译时常量。

另请参阅规范:常量:

常量值由runeintegerfloating-pointimaginarystring字面量、表示常量的标识符、常量表达式、结果为常量的转换或某些内置的结果值表示函数,例如unsafe.Sizeof应用于任何值caplen应用于某些表达式,应用于复数常量realimag复数应用于数值常量。

查看类似的示例(如果不传递它们unsafe.Sizeof()会在运行时出现恐慌或无限期阻塞,但它们工作得很好):

fmt.Println(unsafe.Sizeof(*(*int8)(nil))) // 1, no dereferencing

fmt.Println(unsafe.Sizeof([]int16{}[10])) // 2, no indexing

x := "hi"

fmt.Println(unsafe.Sizeof(x[10]))                          // 1, no indexing

fmt.Println(unsafe.Sizeof(map[interface{}]int{}[[]int{}])) // 8, no indexing

fmt.Println(unsafe.Sizeof((interface{})(nil).(int16)))     // 2, no type assertion

i := 0

fmt.Println(unsafe.Sizeof(i / i)) // 8, no division by 0

i = -1

fmt.Println(unsafe.Sizeof(1 << i))                // 8, no negative shift count

fmt.Println(unsafe.Sizeof(make([]int, i)))        // 24, no negative length

fmt.Println(unsafe.Sizeof((*[1]int)([]int{})))    // 8, no converting to bigger array

fmt.Println(unsafe.Sizeof((func() int32)(nil)())) // 4, no function call

fmt.Println(unsafe.Sizeof(<-(chan int64)(nil)))   // 8, no receiving

var a, b interface{} = []int{}, []int{}

fmt.Println(unsafe.Sizeof(a == b)) // 1, no comparison

在Go Playground上试试这些。



查看完整回答
反对 回复 2022-11-08
  • 1 回答
  • 0 关注
  • 86 浏览
慕课专栏
更多

添加回答

举报

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