为什么不安全。Sizeof被认为不安全?

时间:2018-09-24 14:15:40

标签: go unsafe

请考虑以下内容:

import (
    "log"
    "unsafe"
)

type Foo struct {
    Bar int32
}

func main() {
    log.Println(int(unsafe.Sizeof(Foo{})))
}

为什么确定变量的大小被认为是不安全的,并且是不安全包的一部分?我不明白为什么获取任何类型的大小是不安全的操作,或者为什么要使用哪种机制来确定其大小是必需的。

我也很想知道,对于确定已知结构的大小,不安全软件包是否有替代方案。

2 个答案:

答案 0 :(得分:7)

因为在Go中,如果您需要调用sizeof,通常意味着您直接在操纵内存,而您永远不需要这样做。

如果您来自C语言世界,那么您可能最常使用sizeofmalloc来创建可变长度数组-但是在Go中,您不需要这样做可以简单地make([]Foo, 10)。在Go中,运行时负责分配要分配的内存量。

您应该害怕在真正有意义的地方打电话给unsafe.Sizeof-但您应该问自己是否真正需要它。

即使您正在使用它来编写二进制格式,通常也要自己计算所需的字节数,或者是否有任何使用reflect来动态生成字节的方法:

  • 在结构上调用unsafe.Sizeof还将包括为padding添加的字节数。
  • 在动态大小的结构(例如,切片,字符串)上调用它会产生其标头的长度-您应改为调用len()

unsafeuintptrint上使用uint来确定您运行的是32位还是64位?通常,您可以通过指定int64来避免这种情况,您实际上需要在其中支持大于2 ^ 31的数字。或者,如果您确实需要检测到该错误,则可以使用许多其他选项,例如构建标记或类似的内容:

package main

import (
    "fmt"
)

const is32bit = ^uint(0) == (1 << 32) - 1

func main() {
    fmt.Println(is32bit)
}

答案 1 :(得分:2)

从不安全软件包的外观来看,这些方法的操作并未使用go's类型安全性。

https://godoc.org/unsafe

  

不安全包装中包含的操作会绕过类型安全   进入程序。

     

进口不安全的包裹可能是不可携带的,也不受保护   遵循Go 1兼容性指南。

因此,从声音的角度来看,不安全性在于所提供的代码类型,而不一定是因为专门调用它而引起的