Skip to content

unknown: consistency of address uniqueness of anonymous struct instances #12726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
albertjin opened this issue Sep 23, 2015 · 3 comments
Closed

Comments

@albertjin
Copy link

Go 1.5.1

Let's talk about the following code. The difference among a()/b()/c() is the print output.

package main

import (
    "fmt"
)

func a() {
    var x interface{} = &struct{}{}
    var y interface{} = &struct{}{}
    fmt.Printf("a: %v\n", x == y)
}

func b() {
    var x interface{} = &struct{}{}
    var y interface{} = &struct{}{}
    fmt.Printf("b: %v %p\n", x == y, x)
}

func c() {
    var x interface{} = &struct{}{}
    var y interface{} = &struct{}{}
    fmt.Printf("c: %v %p %p\n", x == y, x, y)
}

func main() {
    a()
    b()
    c()
}

Here goes the output.

a: true
b: false 0x1b59d0
c: true 0x1b59d0 0x1b59d0

It seems that there is some inconsistent optimization that causes the difference. I think that it is more useful for empty anonymous structs to generate unique addresses.

@cznic
Copy link
Contributor

cznic commented Sep 23, 2015

From Size and alignment guarantees:

Two distinct zero-size variables may have the same address in memory.

ie. &struct{}{} == &struct{}{} is explicitly allowed to be true or false.

I think that it is more useful for empty anonymous structs to generate unique addresses.

That would imply sizeof([42]struct{}{}) != 0

@randall77
Copy link
Contributor

Passing x or y to fmt.Printf causes the anonymous structs to escape. They are as a result allocated by the runtime. All zero-sized objects allocated by the runtime are given the same address.

If you don't pass x or y to fmt.Printf, then the anonymous structs they reference are "allocated" on the stack. They happen to get the same address in this instance.

Your middle case generates one runtime allocation and one stack allocation, which is why they are not equal.

I agree that having &struct{}{} generate unique addresses would be marginally more useful than the current situation. But the only way I see to implement that is to treat struct{} as a 1-byte type. At that point, you might as well use a byte object instead (in cases where you care). So I don't see a compelling reason why we should introduce special cases for struct{} into the language.

@bradfitz
Copy link
Contributor

Closing, as I don't think there's anything to do here. This has been discussed at length in the past, which led to https://golang.org/cl/5528053 (fixing #2620). See discussions there.

@golang golang locked and limited conversation to collaborators Sep 23, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants