猿问

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

https://go.dev/play/p/X_BH4qGgXHJ


package main


import (

    "fmt"

    "unsafe"

)


func main() {

    var i *int

    fmt.Println(unsafe.Sizeof(*i)) // dereference of null pointer i

}


为什么这段代码没有


unsafe.Sizeof(*i)

导致运行时恐慌?


慕桂英4014372
浏览 90回答 1
1回答

幕布斯6054654

规格:包装不安全:Alignof对、Offsetof和的调用Sizeof是类型的编译时常量表达式uintptr。这些函数在编译时进行评估,在运行时不会发生实际的取消引用。这是可能的,因为不需要指向的值,只需要有关其类型的信息,不需要取消引用。它也记录在unsafe.Sizeof():Sizeof 的返回值是一个 Go 常量。Go 中的常量是编译时常量。另请参阅规范:常量:常量值由rune、integer、floating-point、imaginary或string字面量、表示常量的标识符、常量表达式、结果为常量的转换或某些内置的结果值表示函数,例如unsafe.Sizeof应用于任何值,cap或len应用于某些表达式,应用于复数常量real和imag复数应用于数值常量。查看类似的示例(如果不传递它们unsafe.Sizeof()会在运行时出现恐慌或无限期阻塞,但它们工作得很好):fmt.Println(unsafe.Sizeof(*(*int8)(nil))) // 1, no dereferencingfmt.Println(unsafe.Sizeof([]int16{}[10])) // 2, no indexingx := "hi"fmt.Println(unsafe.Sizeof(x[10]))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 1, no indexingfmt.Println(unsafe.Sizeof(map[interface{}]int{}[[]int{}])) // 8, no indexingfmt.Println(unsafe.Sizeof((interface{})(nil).(int16)))&nbsp; &nbsp; &nbsp;// 2, no type assertioni := 0fmt.Println(unsafe.Sizeof(i / i)) // 8, no division by 0i = -1fmt.Println(unsafe.Sizeof(1 << i))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 8, no negative shift countfmt.Println(unsafe.Sizeof(make([]int, i)))&nbsp; &nbsp; &nbsp; &nbsp; // 24, no negative lengthfmt.Println(unsafe.Sizeof((*[1]int)([]int{})))&nbsp; &nbsp; // 8, no converting to bigger arrayfmt.Println(unsafe.Sizeof((func() int32)(nil)())) // 4, no function callfmt.Println(unsafe.Sizeof(<-(chan int64)(nil)))&nbsp; &nbsp;// 8, no receivingvar a, b interface{} = []int{}, []int{}fmt.Println(unsafe.Sizeof(a == b)) // 1, no comparison在Go Playground上试试这些。
随时随地看视频慕课网APP

相关分类

Go
我要回答