douya2433 2018-09-24 14:15
浏览 86
已采纳

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

Consider the following:

import (
    "log"
    "unsafe"
)

type Foo struct {
    Bar int32
}

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

Why is determining the size of a variable considered unsafe, and a part of the unsafe package? I don't understand why obtaining the size of any type is an unsafe operation, or what mechanism go uses to determine its size that necessitates this.

I would also love to know if there are any alternatives to the unsafe package for determining size of a known struct.

  • 写回答

2条回答 默认 最新

  • doudian7996 2018-09-24 14:39
    关注

    Because in Go if you need to call sizeof, it generally means you're manipulating memory directly, and you should never need to do that.

    If you come from the C world, you'll probably most often have used sizeof together with malloc to create a variable-length array - but this should not be needed in Go, where you can simply make([]Foo, 10). In Go, the amount of memory to be allocated is taken care of by the runtime.

    You should not be afraid of calling unsafe.Sizeof where it really makes sense - but you should ask yourself whether you actually need it.

    Even if you're using it for, say, writing a binary format, it's generally a good idea to calculate by yourself the number of bytes you need, or if anything generate it dynamically using reflect:

    • calling unsafe.Sizeof on a struct will also include the number of bytes added in for padding.
    • calling it on dynamically-sized structures (ie. slices, strings) will yield the length of their headers - you should call len() instead.

    Using unsafe on a uintptr, int or uint to determine whether you're running on 32-bit or 64-bit? You can generally avoid that by specifying int64 where you actually need to support numbers bigger than 2^31. Or, if you really need to detect that, you have many other options, such as build tags or something like this:

    package main
    
    import (
        "fmt"
    )
    
    const is32bit = ^uint(0) == (1 << 32) - 1
    
    func main() {
        fmt.Println(is32bit)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 易康econgnition精度验证
  • ¥15 线程问题判断多次进入
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致