Skip to content

Commit 1ffb51f

Browse files
authored
Merge pull request #953 from devlights/add-unsafe-alignof-example
Add unsafe_alignof.go
2 parents 649dc3f + e0a0b0c commit 1ffb51f

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

examples/basic/unsafes/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
| unsafe_sizeof.go | unsafe_sizeof | unsafe.Sizeof() についてのサンプルです. |
1313
| unsafe_offsetof.go | unsafe_offsetof | unsafe.Offsetof() のサンプルです |
1414
| unsafe_dump.go | unsafe_dump | unsafeパッケージを使って構造体のメモリダンプを出力するサンプルです |
15+
| unsafe_alignof.go | unsafe_alignof | unsafe.Alignof() のサンプルです |

examples/basic/unsafes/examples.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ func (r *register) Regist(m mapping.ExampleMapping) {
2020
m["unsafe_add"] = Add
2121
m["unsafe_slice"] = Slice
2222
m["unsafe_offsetof"] = Offsetof
23+
m["unsafe_alignof"] = Alignof
2324
m["unsafe_dump"] = Dump
2425
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package unsafes
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"unsafe"
7+
)
8+
9+
// Alignof は、unsafe.Alignof() のサンプルです。
10+
//
11+
// > Alignof takes an expression x of any type and returns the required alignment of a hypothetical variable v as if v was declared via var v = x.
12+
// > It is the largest value m such that the address of v is always zero mod m.
13+
// > It is the same as the value returned by reflect.TypeOf(x).Align().
14+
// > As a special case, if a variable s is of struct type and f is a field within that struct, then Alignof(s.f) will return the required alignment of a field of that type within a struct.
15+
// > This case is the same as the value returned by reflect.TypeOf(s.f).FieldAlign().
16+
// > The return value of Alignof is a Go constant if the type of the argument does not have variable size.
17+
//
18+
// > Alignof は任意の型の式 x を受け取り、var v = x のように宣言されたと仮定した場合の、仮想的な変数 v に必要な**アライメント(配置要求)**を返します。
19+
// > この戻り値は、v のアドレスが常に m で割って余りが 0 となるような最大の正の整数 m です。これは、reflect.TypeOf(x).Align() が返す値と同じです。
20+
// > 特別なケースとして、変数 s が構造体型で、f がその構造体内のフィールドである場合、Alignof(s.f) は構造体内のその型のフィールドに必要なアライメントを返します
21+
// > このケースは reflect.TypeOf(s.f).FieldAlign() が返す値と同じです。
22+
// > 引数の型が可変サイズを持たない場合、Alignof の戻り値はGoの定数になります。
23+
//
24+
// REFERENCES:
25+
// - https://pkg.go.dev/unsafe@go1.25.3#Alignof
26+
func Alignof() error {
27+
type (
28+
S1 struct {
29+
A uint8 // offset=0, size=1, padding=3
30+
B uint32 // offset=4, size=4, padding=0
31+
C uint64 // offset=8, size=8, padding=0
32+
D uint16 // offset=16, size=2, padding=6
33+
}
34+
S2 struct {
35+
A uint8 // offset=0, size=1, padding=1
36+
B uint16 // offset=2, size=2, padding=0
37+
C uint8 // offset=4, size=1, padding=0
38+
D uint8 // offset=5, size=1, padding=0
39+
}
40+
)
41+
var (
42+
s1 = S1{math.MaxUint8, math.MaxUint32, math.MaxUint64, math.MaxUint16}
43+
s2 = S2{math.MaxUint8, math.MaxUint16, math.MaxUint8, math.MaxUint8}
44+
)
45+
fmt.Printf("S1 Alignment Size: %d\n", unsafe.Alignof(s1)) // C言語と同様に構造体内での最大アライメント要件を持つ型のサイズとなる (uint64)
46+
fmt.Printf("S1 Size : %d\n", unsafe.Sizeof(s1))
47+
fmt.Printf("S2 Alignment Size: %d\n", unsafe.Alignof(s2)) // C言語と同様に構造体内での最大アライメント要件を持つ型のサイズとなる (uint16)
48+
fmt.Printf("S2 Size : %d\n", unsafe.Sizeof(s2))
49+
50+
return nil
51+
}

0 commit comments

Comments
 (0)