Does Go guarantee constant addresses?

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?

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.