I don't think this case really applies here. I get that comparison of a==b may or may not be true. The problem is that if a==b at some point in a program, it should be the case that a==b for all other cases in that same program. That is, if a==b, then interface{}(a)==interface{}(b), and vice versa. But what we have here is a!=b but interface{}(a)==interface{}(b)
On Thu, Feb 22, 2024 at 9:50 AM Axel Wagner <axel.wagner...@googlemail.com> wrote: > > Hm actually, the spec allows for this, technically speaking: > https://go.dev/ref/spec#Comparison_operators > > > Pointers to distinct zero-size variables may or may not be equal. > > Arguably, this genuinely would allow comparison of pointers to zero-sized > variables to have any behavior whatsoever (including being random). But it > certainly is confusing. > > > On Thu, Feb 22, 2024 at 5:46 PM Axel Wagner <axel.wagner...@googlemail.com> > wrote: >> >> I see. Sorry, I was jumping to conclusions and didn't quite get what you >> mean. That is my fault. >> >> I agree that this looks confusing and is arguably a bug. I filed >> https://github.com/golang/go/issues/65878, thanks for pointing it out. >> >> On Thu, Feb 22, 2024 at 5:20 PM burak serdar <bser...@computer.org> wrote: >>> >>> Creating an interface is not creating a pointer to a zero sized variable. >>> >>> a==b prints false. That means, a and b point to different locations >>> Bar(a)==Bar(b) prints true. If a!=b, then Bar(a) must be different from >>> Bar(b) >>> >>> On Thu, Feb 22, 2024 at 9:15 AM Axel Wagner >>> <axel.wagner...@googlemail.com> wrote: >>> > >>> > If you expect that, you are misreading the spec. There is no guarantee of >>> > any behavior here. An implementation is allowed to flip a coin, every >>> > time you create a pointer to a zero-sized variable, and either return a >>> > unique pointer or a singleton. I think you may assume that &a == &a, >>> > always. But apart from that, who knows. >>> > >>> > Zero-sized variables *may* have the same address. They don't *have* to. >>> > >>> > On Thu, Feb 22, 2024 at 5:12 PM burak serdar <bser...@computer.org> wrote: >>> >> >>> >> On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner >>> >> <axel.wagner...@googlemail.com> wrote: >>> >> > >>> >> > Note that in the Spec section I quoted above it says "Two distinct >>> >> > zero-size variables may have the same address in memory" (emphasis >>> >> > mine). >>> >> > There is no guarantee, that all zero-sized values have the same >>> >> > address (otherwise, you'd get into inefficiencies when taking the >>> >> > address of a zero-sized field in a larger struct, or when converting a >>> >> > zero-capacity slice into an array-pointer). But it is allowed. >>> >> > If you require two pointers returned from different code paths to be >>> >> > different, for correctness, then you have to make them point at >>> >> > something that has non-zero size. Otherwise, all potential >>> >> > combinations are valid according to the spec. >>> >> >>> >> Yes. But in that case, you'd expect either a==b and Bar(a)==Bar(b) to >>> >> be both true, or both false. In this case, one is true and the other >>> >> is not. >>> >> >>> >> >>> >> > >>> >> > On Thu, Feb 22, 2024 at 4:53 PM burak serdar <bser...@computer.org> >>> >> > wrote: >>> >> >> >>> >> >> The compiler can allocate the same address for empty structs, so I >>> >> >> actually expected a==b to be true, not false. However, there's >>> >> >> something more interesting going on here because: >>> >> >> >>> >> >> a := &Foo{} >>> >> >> b := &Foo{} >>> >> >> fmt.Printf("%t\n", *a == *b) >>> >> >> fmt.Printf("%t\n", a == b) >>> >> >> fmt.Printf("%p %p\n", a, b) >>> >> >> x := Bar(a) >>> >> >> y := Bar(b) >>> >> >> fmt.Printf("%t\n", Bar(a) == Bar(b)) >>> >> >> fmt.Printf("%t\n", x == y) >>> >> >> >>> >> >> Prints: >>> >> >> >>> >> >> true >>> >> >> true >>> >> >> 0x58e360 0x58e360 // Note that a and be are pointing to the same >>> >> >> address >>> >> >> true >>> >> >> true >>> >> >> >>> >> >> >>> >> >> But: >>> >> >> a := &Foo{} >>> >> >> b := &Foo{} >>> >> >> fmt.Printf("%t\n", *a == *b) >>> >> >> fmt.Printf("%t\n", a == b) >>> >> >> //fmt.Printf("%p %p\n", a, b) // Comment out the print >>> >> >> x := Bar(a) >>> >> >> y := Bar(b) >>> >> >> fmt.Printf("%t\n", Bar(a) == Bar(b)) >>> >> >> fmt.Printf("%t\n", x == y) >>> >> >> >>> >> >> >>> >> >> Prints: >>> >> >> >>> >> >> true >>> >> >> false >>> >> >> true >>> >> >> true >>> >> >> >>> >> >> >>> >> >> On Thu, Feb 22, 2024 at 3:56 AM Brien Colwell <xcolw...@gmail.com> >>> >> >> wrote: >>> >> >> > >>> >> >> > I'm confused by this output. It appears that the interface of two >>> >> >> > different pointers to an empty struct are equal. In all other >>> >> >> > cases, interface equality seems to be the pointer equality. What's >>> >> >> > going on in the empty struct case? >>> >> >> > >>> >> >> > ``` >>> >> >> > package main >>> >> >> > >>> >> >> > import "fmt" >>> >> >> > >>> >> >> > type Foo struct { >>> >> >> > } >>> >> >> > >>> >> >> > func (self *Foo) Hello() { >>> >> >> > } >>> >> >> > >>> >> >> > type FooWithValue struct { >>> >> >> > A int >>> >> >> > } >>> >> >> > >>> >> >> > func (self *FooWithValue) Hello() { >>> >> >> > } >>> >> >> > >>> >> >> > type Bar interface { >>> >> >> > Hello() >>> >> >> > } >>> >> >> > >>> >> >> > func main() { >>> >> >> > a := &Foo{} >>> >> >> > b := &Foo{} >>> >> >> > fmt.Printf("%t\n", *a == *b) >>> >> >> > fmt.Printf("%t\n", a == b) >>> >> >> > fmt.Printf("%t\n", Bar(a) == Bar(b)) >>> >> >> > >>> >> >> > c := &FooWithValue{A: 1} >>> >> >> > d := &FooWithValue{A: 1} >>> >> >> > fmt.Printf("%t\n", *c == *d) >>> >> >> > fmt.Printf("%t\n", c == d) >>> >> >> > fmt.Printf("%t\n", Bar(c) == Bar(d)) >>> >> >> > } >>> >> >> > ``` >>> >> >> > >>> >> >> > Prints (emphasis added on the strange case): >>> >> >> > >>> >> >> > ``` >>> >> >> > true >>> >> >> > false >>> >> >> > **true** >>> >> >> > true >>> >> >> > false >>> >> >> > false >>> >> >> > ``` >>> >> >> > >>> >> >> > >>> >> >> > -- >>> >> >> > You received this message because you are subscribed to the Google >>> >> >> > Groups "golang-nuts" group. >>> >> >> > To unsubscribe from this group and stop receiving emails from it, >>> >> >> > send an email to golang-nuts+unsubscr...@googlegroups.com. >>> >> >> > To view this discussion on the web visit >>> >> >> > https://groups.google.com/d/msgid/golang-nuts/d93760c9-61a7-4a3c-9b5c-d89f023d2253n%40googlegroups.com. >>> >> >> >>> >> >> -- >>> >> >> You received this message because you are subscribed to the Google >>> >> >> Groups "golang-nuts" group. >>> >> >> To unsubscribe from this group and stop receiving emails from it, >>> >> >> send an email to golang-nuts+unsubscr...@googlegroups.com. >>> >> >> To view this discussion on the web visit >>> >> >> https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqrq21ymUJ00ni_JV%3Dkv6itqZg51GoWM5zJNjcGU1BKcuA%40mail.gmail.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoLCXRe9SK74LrKdesxav%2BBdNCUeZx2iDSkJPFzw%3D_zgQ%40mail.gmail.com.