What is really fantastical is that a==b prints false, even though the 
pointers are actually the same. I am guessing some sort of optimization 
effect is at play here. 

https://go.dev/play/p/Dsqeh_aAXKT

type Foo struct {
}

func main() {

a := &Foo{}
b := &Foo{}
fmt.Printf("%t\n", *a == *b)
fmt.Printf("%t\n", a == b)
q := uintptr(unsafe.Pointer(a))
r := uintptr(unsafe.Pointer(b))
//fmt.Printf("%p %p\n", a, b)
fmt.Printf("%t\n", q == r)
fmt.Printf("%x %x\n", q, r)
} 

prints:

true 
false 
true 
c000104ee0 c000104ee0

wild! (or am I missing something?)
On Thursday, February 22, 2024 at 1:07:08 PM UTC-5 Axel Wagner wrote:

> On Thu, Feb 22, 2024 at 6:44 PM burak serdar <bse...@computer.org> wrote:
>
>> 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.
>
>
> Well, given that the spec is *not* saying what you say it maybe should - 
> it seems we are in agreement. It is indeed correct for `x` to may or not be 
> equal to `y` here, with the spec as it is right now.
>  
>
>> 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.wa...@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.wa...@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 <bse...@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.wa...@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 <
>> bse...@computer.org> wrote:
>> >> >>> >>
>> >> >>> >> On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner
>> >> >>> >> <axel.wa...@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 <
>> bse...@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 <
>> xcol...@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...@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...@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/682fbdcb-546c-4f38-81e8-f9fcfc8f0403n%40googlegroups.com.

Reply via email to