gpt4 book ai didi

go - 为什么这两个结构在内存中的大小不同?

转载 作者:IT王子 更新时间:2023-10-29 01:24:23 26 4
gpt4 key购买 nike

假设我有这两个结构:

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
}

A 的大小为 6 个字节。但是,B 的大小是 4 个字节。
我认为这与它们在内存中的布局有关,但我不确定我是否理解为什么会这样。
编译器不能检测和优化的东西吗? (重新排列字段顺序)

Link to the code

最佳答案

由于对齐而填充。

The Go Programming Language Specification

Size and alignment guarantees

For the numeric types, the following sizes are guaranteed:

type                                 size in bytes

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

The following minimal alignment properties are guaranteed:

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

  • For a variable x of struct type: unsafe.Alignof(x) is the largest of all the values unsafe.Alignof(x.f) for each field f of x, but at least 1.

  • For a variable x of array type: unsafe.Alignof(x) is the same as the alignment of a variable of the array's element type.

A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.


例如,

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(a.x), unsafe.Offsetof(a.y), unsafe.Offsetof(a.z))
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(b.x), unsafe.Offsetof(b.y), unsafe.Offsetof(b.z))
}

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

输出:

A:
Size: 6
Address: 0x10410020 0x10410022 0x10410024
Offset: 0 2 4

B:
Size: 4
Address: 0x10410040 0x10410041 0x10410042
Offset: 0 1 2

您可能正在匹配一个外部struct,也许是另一种语言。您可以告诉编译器您想要什么。编译器不会猜测。

关于go - 为什么这两个结构在内存中的大小不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48753195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com