In Go, the order in which struct fields are declared can affect the size of the struct. Why?
type A struct { a bool b int64 c int } type B struct { b int64 a bool c int }
Printing the sizes of these structs reveals:
fmt.Println(unsafe.Sizeof(A{})) // Output: 24 fmt.Println(unsafe.Sizeof(B{})) // Output: 16
Even though they have the same fields, their sizes differ.
Whether fields are aligned or start at specific memory addresses depends on the target architecture. For instance, int64 requires 8-byte alignment. In A, the first field is bool, which is 1 byte. To align b (int64) correctly, there is a 7-byte implicit padding after a.
In B, since a is followed by int (4 bytes), only 3 bytes of padding are needed. This explains the difference in sizes.
// Offset (in bytes) for struct A fmt.Println(unsafe.Offsetof(a.a)) // Output: 0 fmt.Println(unsafe.Offsetof(a.b)) // Output: 8 fmt.Println(unsafe.Offsetof(a.c)) // Output: 16 // Offset for struct B fmt.Println(unsafe.Offsetof(b.b)) // Output: 0 fmt.Println(unsafe.Offsetof(b.a)) // Output: 8 fmt.Println(unsafe.Offsetof(b.c)) // Output: 12
type C struct {}
The size of a zero-size struct is zero, indicating no memory allocation. Despite distinct variables referencing zero-size structs, they may share the same memory address:
a := C{} b := C{} c := [0]int{} d := [3]C{} fmt.Printf("%p %p %p %p %p", &a, &b, &c, &d, &d[2])
Output:
0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c
All addresses are the same, indicating no memory allocation for these zero-size variables.
Struct field ordering can impact size due to alignment requirements and implicit padding. Zero-size structs optimize memory usage by allocating no memory and potentially sharing the same address for distinct variables.
The above is the detailed content of Why Does Struct Field Order Affect the Size of Go Structs?. For more information, please follow other related articles on the PHP Chinese website!