为什么不安全。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.

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)
}

From the looks of the unsafe package the methods don't use go's type safety for their operations.

https://godoc.org/unsafe

Package unsafe contains operations that step around the type safety of Go programs.

Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.

So from the sounds of it the unsafe-ness is in the kind of code being provided, not necessarily from calling it in particular