Does Go guarantee constant addresses?

霸气de小男生 提交于 2021-01-20 19:13:38

问题


Given an object obj is there a guarantee that

uintptr(unsafe.Pointer(&obj))

will always evaluate to the same value regardless of when it is called?

Of course, Go guarantees that if you take two pointers to the same object, they will always compare equal. It might be possible though that an implementation moves an object in memory and transparently updates all pointers to it.

This is interesting if you consider garbage collection strategies like Mark-and-Compact. Would an implementor be allowed to use such a garbage collection strategy?


回答1:


There is no such guarantee, exactly so that it is possible to implement a moving collector.

In fact, although the garbage collector does not move heap objects today, in Go 1.3 stacks can move when needing to grow, so it is entirely possible that

var obj int
fmt.Println(uintptr(unsafe.Pointer(&obj)))
bigFunc()
fmt.Println(uintptr(unsafe.Pointer(&obj)))

will print two different pointers, because bigFunc grew the stack, causing obj and everything else on the stack to move.




回答2:


There isn't anything in the specification that guarantees this, probably to allow implementations of the language to use compacting garbage collectors in the future. In this golang-nuts thread one of the developers suggests that a compacting GC would be possible provided unsafe.Pointer values were pinned in memory, but this couldn't extend to all unitptr values.

For the current Go runtime I believe it is true, but relying on it would still be undefined behaviour. There are a few caveats though:

  1. If obj is a zero size type, the value of the expression may not be unique, as described in the spec.

  2. Over the lifetime of a program, a particular uintptr value might refer to different objects.




回答3:


No absolute guarantee. Especially if Go adds compaction to its mark and sweep garbage collector.

Addresses stored in pointer types and type unsafe.Pointer will be updated, if necessary, by any garbage collector. Addresses stored in type uintptr as unsigned integers will not be updated by a garbage collector. The uintptr type is not a pointer type, it's an integer type.

Numeric types

uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value

converting unsafe.Pointers to uintptr

Pointers should have been kept in unsafe.Pointers - not uintptrs - always.

Russ

For your example,

uintptr(unsafe.Pointer(&obj))

you have an unsigned integer, not an address.



来源:https://stackoverflow.com/questions/22195919/does-go-guarantee-constant-addresses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!