On Thu, Feb 22, 2024 at 10:39 AM Axel Wagner <axel.wagner...@googlemail.com> wrote: > > > > On Thu, Feb 22, 2024 at 6:06 PM burak serdar <bser...@computer.org> wrote: >> >> 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. > > > Why? I mean, I get that it makes sense intuitively, but how does this follow > from the spec? That sentence says "a comparison of two pointers to zero sized > values may or may not be true". It does not qualify that statement in any way.
We are comparing two interfaces containing pointers to zero-size structs. If those pointers are not equal, then the interfaces should not be equal as well. Maybe the spec should be clarified to say "for a compilation of a program, two pointers to zero-size variables may or may not be equal", because otherwise it implies that if you have x:= a==b y:= a==b x may or may not be true. If a==b, then that should hold for every execution of that program, and throughout the 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/CAMV2Rqp43eyz8%2B59-W6szDdZ0oqrHxXf67Fp3fgDb6Qj1ByRSQ%40mail.gmail.com.