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