Package unsafe
…
The function
Offsetof
takes a (possibly parenthesized) selectors.f
, denoting a fieldf
of the struct denoted bys
or*s
, and returns the field offset in bytes relative to the struct’s address. Iff
is an embedded field, it must be reachable without pointer indirections through fields of the struct. For a structs
with fieldf
:uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
I expect this is neither too confusing, nor too useful for most of us. But let’s use an example to make it glaringly obvious, just the same.
Let’s recall what we learned Wednesday about Sizeof
, and apply it to a struct:
type X struct {
A int
B string
C float64
}
var x X
fmt.Println("X:"unsafe.Sizeof(x))
fmt.Println("X.A:", unsafe.Sizeof(x.A))
fmt.Println("X.B:", unsafe.Sizeof(x.B))
fmt.Println("xX.C:", unsafe.Sizeof(x.C))
On a 64-bit system, this little program should output:
X: 32
X.A: 8
X.B: 16
X.C: 8
So now, what are the offsets of x.A, x.B, and x.C? Simple arithmetic would suggest: 0, 0 + 8 (8), and 0 + 8 + 16 (24) respectively. Let’s see:
fmt.Println("X.A offset:", unsafe.Offsetof(x.A))
fmt.Println("X.B offset:", unsafe.Offsetof(x.B))
fmt.Println("X.C offset:", unsafe.Offsetof(x.C))
And indeed, we find the output is:
X.A offset: 0
X.B offset: 8
X.C offset: 24
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)