为什么 Go 在 mod 8 之后的 4 字节对齐结构地址在 64 位架构中是 4?
Why Go's 4bytes aligned struct address after mod 8 is 4 in 64-bit arch?
当我研究sync.WaitGroup中的代码时,
我注意到 WaitGroup 使用 state1([3]uint32) 字段为状态原子存储假设一个 64 位对齐指针。
像这样:
// https://github.com/golang/go/issues/19149
type WaitGroup struct {
noCopy noCopy
state1 [3]uint32
}
// state returns pointers to the state and sema fields stored within wg.state1.
func (wg *WaitGroup) state() (statep *uint64, semap *uint32) {
if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {
return (*uint64)(unsafe.Pointer(&wg.state1)), &wg.state1[2]
} else {
return (*uint64)(unsafe.Pointer(&wg.state1[1])), &wg.state1[0]
}
}
但是当我在 mac 和 linux 上查看时,
在64位系统上,第一个分配的4字节对齐的数据结构地址显示在mod8之后是4,而在32位系统上是 0.
很好奇在golang中是怎么保证的?
代码在这里:https://play.golang.org/p/oiZMHd2c0I6
// 32-bit system:
// GOARCH=386 go run main.go
// 0 4 0 //why first address mod 8 is 0
// 64-bit system:
// go run main.go
// 4 0 4 //why first address mod 8 is 4
更新:
使用@Renat 的回答地址,不能保证变量地址。
输出可能不一致。
来自 golang.org :
Computer architectures may require memory addresses to be aligned;
that is, for addresses of a variable to be a multiple of a factor, the
variable's type's alignment. The function Alignof takes an expression
denoting a variable of any type and returns the alignment of the (type
of the) variable in bytes.
因此鉴于 Alignof(c)
是 4
,它将与 4
对齐,不需要 8
字节。
创建另一个对象时 M
var c = M{}
var d = M{}
println(
unsafe.Sizeof(c),
unsafe.Alignof(c),
uintptr(unsafe.Pointer(&c.x))%8,
)
println(
" ",
uintptr(unsafe.Pointer(&d.x))%8,
)
我得到了:
12 4 4
0
当我研究sync.WaitGroup中的代码时, 我注意到 WaitGroup 使用 state1([3]uint32) 字段为状态原子存储假设一个 64 位对齐指针。
像这样:
// https://github.com/golang/go/issues/19149
type WaitGroup struct {
noCopy noCopy
state1 [3]uint32
}
// state returns pointers to the state and sema fields stored within wg.state1.
func (wg *WaitGroup) state() (statep *uint64, semap *uint32) {
if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {
return (*uint64)(unsafe.Pointer(&wg.state1)), &wg.state1[2]
} else {
return (*uint64)(unsafe.Pointer(&wg.state1[1])), &wg.state1[0]
}
}
但是当我在 mac 和 linux 上查看时, 在64位系统上,第一个分配的4字节对齐的数据结构地址显示在mod8之后是4,而在32位系统上是 0.
很好奇在golang中是怎么保证的?
代码在这里:https://play.golang.org/p/oiZMHd2c0I6
// 32-bit system:
// GOARCH=386 go run main.go
// 0 4 0 //why first address mod 8 is 0
// 64-bit system:
// go run main.go
// 4 0 4 //why first address mod 8 is 4
更新: 使用@Renat 的回答地址,不能保证变量地址。 输出可能不一致。
来自 golang.org :
Computer architectures may require memory addresses to be aligned; that is, for addresses of a variable to be a multiple of a factor, the variable's type's alignment. The function Alignof takes an expression denoting a variable of any type and returns the alignment of the (type of the) variable in bytes.
因此鉴于 Alignof(c)
是 4
,它将与 4
对齐,不需要 8
字节。
创建另一个对象时 M
var c = M{}
var d = M{}
println(
unsafe.Sizeof(c),
unsafe.Alignof(c),
uintptr(unsafe.Pointer(&c.x))%8,
)
println(
" ",
uintptr(unsafe.Pointer(&d.x))%8,
)
我得到了:
12 4 4
0