为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在 64 位拱门中 mod 8 后 Go 的 4 字节对齐结构地址是 4?

为什么在 64 位拱门中 mod 8 后 Go 的 4 字节对齐结构地址是 4?

Go
翻过高山走不出你 2022-05-18 09:43:02
当我研究 sync.WaitGroup 中的代码时,我注意到 WaitGroup 使用 state1([3]uint32) 字段来假设状态原子存储的 64 位对齐指针。像这样:// https://github.com/golang/go/issues/19149type 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 字节对齐数据结构地址显示在 mod 8 之后是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 的答案地址,不能保证变量地址。输出可能不包含。
查看完整描述

1 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

来自golang.org:


计算机架构可能需要对齐内存地址;也就是说,对于一个变量的地址是一个因子的倍数,变量的类型的对齐。函数 Alignof 接受一个表示任何类型变量的表达式,并以字节为单位返回变量(类型)的对齐方式。


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


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信