I’d like to report an intriguing behavior regarding the pointer equality of zero-width types. Apologies if this is trivial or a known issue.
The two codes below appear to be identical, yet the results of &a == &b
differ. It seems predictable that “variables go into separate addresses on the stack, unless pointers are needed”, as opposed to “variables escape to the same address on the heap, when pointers are needed,”.
// go1.20.5 darwin/arm64
// go run input.go
func main() {
var a, b struct{}
fmt.Println(&a == &b) // false
}
// go build -gcflags="-m -N -l" -o output input.go
// # command-line-arguments
// ./input.go:9:13: ... argument does not escape
// ./input.go:9:17: &a == &b escapes to heap
// go1.20.5 darwin/arm64
// go run input.go
func main() {
var a, b struct{}
fmt.Println(&a == &b) // true
fmt.Printf("%p\n", &a) // 0x1172f60 *depends on env
fmt.Printf("%p\n", &b) // 0x1172f60 *depends on env
}
// go build -gcflags="-m -N -l" -o output input.go
// # command-line-arguments
// ./input.go:8:6: moved to heap: a
// ./input.go:8:9: moved to heap: b
// ./input.go:9:13: ... argument does not escape
// ./input.go:9:17: &a == &b escapes to heap
// ./input.go:10:12: ... argument does not escape
// ./input.go:11:12: ... argument does not escape
Is this defined behavior, undefined behavior, or a bug?
Please provide any insights or feedback that you might have.
Thanks.