go - 为什么 unsafe.Sizeof 被认为是不安全的?

标签 go unsafe

考虑以下几点:

import (
    "log"
    "unsafe"
)

type Foo struct {
    Bar int32
}

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

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

我也很想知道是否有任何替代 unsafe 包的方法来确定已知结构的大小。

最佳答案

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

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

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

即使您使用它来编写二进制格式,您自己计算所需的字节数通常是个好主意,或者如果有任何东西使用 reflect 动态生成它:

  • 在结构上调用unsafe.Sizeof 还将包括为padding 添加的字节数。 .
  • 在动态大小的结构(即 slice 、字符串)上调用它会产生其 header 的长度 - 您应该改为调用 len()

uintptrintuint 上使用 unsafe 来确定您是否在 32- 上运行位还是 64 位?您通常可以通过在实际需要支持大于 2^31 的数字处指定 int64 来避免这种情况。或者,如果您真的需要检测它,您还有许多其他选择,例如构建标签或类似的东西:

package main

import (
    "fmt"
)

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

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

关于go - 为什么 unsafe.Sizeof 被认为是不安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52481330/

相关文章:

c# - 如何在 "visual studio code"中运行不安全代码?

json - 在 go 模板中加入范围 block

go - 如何为可以使用 len() 的东西编写 Go 类型约束?

Mysql自增Id在使用prepared statements时不按顺序

c++ - 错误 C4996 : 'ctime' : This function or variable may be unsafe

c# - 如何检测我正在加载的 .NET 程序集是否包含不安全代码?

c# - 从字符串转换为 char* 仅复制第一个字符

c# - 如何在没有副本的情况下将结构转换为字节数组?

go - 如何从文件中读取 RSA key

go - scanf 值在终端中作为命令执行