Why do these two structures have different sizes in memory?

Suppose I have these two structures:

package main import ( "fmt" "unsafe" ) type A struct { int8 int16 bool } type B struct { int8 bool int16 } func main() { fmt.Println(unsafe.Sizeof(A{}), unsafe.Sizeof(B{})) // 6 4 } 

Size A is 6 bytes. however, size B is 4 bytes.
I suppose this is due to their location in memory, but I'm not sure I understand why he behaves this way. Not that the compiler can detect and optimize? (reorder fields)

Code Link

+5
source share
1 answer

Filling due to alignment.

Go programming language specification

Size and alignment guarantees

The following sizes are guaranteed for numeric types:

 type size in bytes byte, uint8, int8 1 uint16, int16 2 uint32, int32, float32 4 uint64, int64, float64, complex64 8 complex128 16 

The following minimum alignment properties are guaranteed:

  • For a variable x of any type: unsafe.Alignof (x) is at least 1.

  • For a variable x of type struct: unsafe.Alignof (x) is the largest of all unsafe.Alignof (xf) values ​​for each field f of x, but not less than 1.

  • For an array type variable x: unsafe.Alignof (x) matches the alignment of an array element type variable.

The type of a structure or array is 0 if it does not contain fields (or elements, respectively) whose size is greater than zero. Two different zero-sized variables can have the same memory address.


For instance,

 package main import ( "fmt" "unsafe" ) type A struct { x int8 y int16 z bool } type B struct { x int8 y bool z int16 } func main() { var a A fmt.Println("A:") fmt.Println("Size: ", unsafe.Sizeof(a)) fmt.Printf("Address: %p %p %p\n", &a.x, &a.y, &a.z) fmt.Printf("Offset: %d %d %d\n", unsafe.Offsetof(ax), unsafe.Offsetof(ay), unsafe.Offsetof(az)) fmt.Println() var b B fmt.Println("B:") fmt.Println("Size: ", unsafe.Sizeof(b)) fmt.Printf("Address: %p %p %p\n", &b.x, &b.y, &b.z) fmt.Printf("Offset: %d %d %d\n", unsafe.Offsetof(bx), unsafe.Offsetof(by), unsafe.Offsetof(bz)) } 

Playground: https://play.golang.org/p/_8yDMungDg0

Output:

 A: Size: 6 Address: 0x10410020 0x10410022 0x10410024 Offset: 0 2 4 B: Size: 4 Address: 0x10410040 0x10410041 0x10410042 Offset: 0 1 2 

Perhaps you are using an external struct , perhaps in a different language. It is up to you to tell the compiler what you want. The compiler will not guess.

+9
source

Source: https://habr.com/ru/post/1275325/


All Articles