// run // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import "unsafe" type T struct { X int } var t T func isUintptr(uintptr) {} type T2 struct { A int32 U2 } type U2 struct { B int32 C int32 } var t2 T2 var p2 *T2 func main() { // Test unsafe.Sizeof, unsafe.Alignof, and unsafe.Offsetof all return uintptr. isUintptr(unsafe.Sizeof(t)) isUintptr(unsafe.Alignof(t)) isUintptr(unsafe.Offsetof(t.X)) // Test correctness of Offsetof with respect to embedded fields (issue 4909). if unsafe.Offsetof(t2.C) != 8 { println(unsafe.Offsetof(t2.C), "!= 8") panic("unsafe.Offsetof(t2.C) != 8") } if unsafe.Offsetof(p2.C) != 8 { println(unsafe.Offsetof(p2.C), "!= 8") panic("unsafe.Offsetof(p2.C) != 8") } if unsafe.Offsetof(t2.U2.C) != 4 { println(unsafe.Offsetof(t2.U2.C), "!= 4") panic("unsafe.Offsetof(t2.U2.C) != 4") } if unsafe.Offsetof(p2.U2.C) != 4 { println(unsafe.Offsetof(p2.U2.C), "!= 4") panic("unsafe.Offsetof(p2.U2.C) != 4") } testDeep() testNotEmbedded() } type ( S1 struct { A int64 S2 } S2 struct { B int64 S3 } S3 struct { C int64 S4 } S4 struct { D int64 S5 } S5 struct { E int64 S6 } S6 struct { F int64 S7 } S7 struct { G int64 S8 } S8 struct { H int64 *S1 } ) func testDeep() { var s1 S1 switch { case unsafe.Offsetof(s1.A) != 0: panic("unsafe.Offsetof(s1.A) != 0") case unsafe.Offsetof(s1.B) != 8: panic("unsafe.Offsetof(s1.B) != 8") case unsafe.Offsetof(s1.C) != 16: panic("unsafe.Offsetof(s1.C) != 16") case unsafe.Offsetof(s1.D) != 24: panic("unsafe.Offsetof(s1.D) != 24") case unsafe.Offsetof(s1.E) != 32: panic("unsafe.Offsetof(s1.E) != 32") case unsafe.Offsetof(s1.F) != 40: panic("unsafe.Offsetof(s1.F) != 40") case unsafe.Offsetof(s1.G) != 48: panic("unsafe.Offsetof(s1.G) != 48") case unsafe.Offsetof(s1.H) != 56: panic("unsafe.Offsetof(s1.H) != 56") case unsafe.Offsetof(s1.S1) != 64: panic("unsafe.Offsetof(s1.S1) != 64") case unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 8: panic("unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 8") } } func testNotEmbedded() { type T2 struct { B int32 C int32 } type T1 struct { A int32 T2 } type T struct { Dummy int32 F T1 P *T1 } var t T var p *T switch { case unsafe.Offsetof(t.F.B) != 4: panic("unsafe.Offsetof(t.F.B) != 4") case unsafe.Offsetof(t.F.C) != 8: panic("unsafe.Offsetof(t.F.C) != 8") case unsafe.Offsetof(t.P.B) != 4: panic("unsafe.Offsetof(t.P.B) != 4") case unsafe.Offsetof(t.P.C) != 8: panic("unsafe.Offsetof(t.P.C) != 8") case unsafe.Offsetof(p.F.B) != 4: panic("unsafe.Offsetof(p.F.B) != 4") case unsafe.Offsetof(p.F.C) != 8: panic("unsafe.Offsetof(p.F.C) != 8") case unsafe.Offsetof(p.P.B) != 4: panic("unsafe.Offsetof(p.P.B) != 4") case unsafe.Offsetof(p.P.C) != 8: panic("unsafe.Offsetof(p.P.C) != 8") } }