On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier <eikeme...@fillmore-labs.com>
wrote:

>
> Am 20.06.2024 um 13:24 schrieb Axel Wagner <axel.wagner...@googlemail.com
> >:
>
> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2.
> in your example, the two `unsafe.Pointers` do not point to the same
> variable and do not have the value `nil` and 3. are not pointing at
> distinct zero-sized variables. So their comparison should be `false`, which
> is what your example observes.
>
>
> Does it (Go Playground <https://go.dev/play/p/230UNKVQl0A>)?
>
> func f5() {
> var (
> a  struct{}
> b  int
> aa = (*int)(unsafe.Pointer(&a))
> ba = (*int)(unsafe.Pointer(&b))
> eq = aa == ba
> )
>
> println("&a:", aa, reflect.TypeOf(aa).String())
> println("&b:", ba, reflect.TypeOf(ba).String())
> println("&a == &b:", eq)
> cmpIntPtr(aa, ba)
> }
>
> func cmpIntPtr(p1 *int, p2 *int) {
> fmt.Println("p1 == p2:", p1 == p2)
> }
>
> &a: 0xc0000466f8 *int
> &b: 0xc0000466f8 *int
> &a == &b: falsep1 == p2: true
>
>
Interestingly, the spec does not forbid that (or specifies it as
implementation-defined), though the (implementation-defined) unsafe.Pointer
rules <https://pkg.go.dev/unsafe#Pointer> do, as using `unsafe.Pointer` to
convert between pointers of different base types is only allowed if the
target variable is at least as large as the source variable and both share
an equivalent memory layout.

I think the fact that the spec does not put any limits on the allowed
behaviour of converting between `unsafe.Pointer` and other pointer types is
a clear oversight that should be corrected (perhaps it should really be
"The effect of converting between Pointer and uintptr is
implementation-defined" should really say "and other types"). But I don't
think it's a surprising fact that you can make a program behave in almost
arbitrary ways by doing that.


> I’m advocating for at least a FAQ article,
>
>
> I tend to agree, though I'm not sure how to phrase that, beyond saying "do
> not make any assumptions about the identity pointers to zero-sized
> variables or with zero-sized base types or that where derived from one of
> those" and I'm not sure how helpful that is.
>
>
> It seems like a frequently asked question to me ;)
>

It is. But note that every time it is asked, it leads to considerable
discussion, which seems to strongly suggest that it is hard to give a
simple, unambiguous answer that people find satisfying.

I think you should acknowledge that the spec *is* already trying to be very
clear about this. The fact that you can poke holes in it is because writing
a spec unambiguously is hard. But the two quoted phrases are there in the
best attempt to clearly state that you can not rely on any assumptions
about pointers to zero-sized variables - within the somewhat abstract
framework of the spec. Feel free to propose a better one, I'm not actually
arguing against that.

And I'm also not arguing against an FAQ entry. Ideally, someone would
suggest a phrasing that is sufficiently broad and unambiguous and clear to
cover any version of this question people might ask, while also not
contradicting the spec.


> but also think the specification should be adapted, for clarity but also
>> for the fact that only one pointer pointing to a zero-sized variable can
>> compare differently to anything over time, even things having the same
>> address value.
>>
>
> Note that "address value" is not something that exists within the spec. As
> for clarifying the spec here, maybe. I do think the behavior is covered, as
> I outlined above. And as above, I'm not sure how to clarify it further,
> while still leaving up the space we want to left open.
>
>
> I vote for making this openness explicit, meaning that even the optimizer
> is free to make assumptions that do not hold during runtime. So if you have
> a pointer derived from something pointing to a zero-size type it can
> compare with different results over time, even false when having the same
> value. I do not believe that is what’s currently in the spec.
>

> Cheers
> Oliver
>
>

-- 
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/CAEkBMfGOWoQYrQ9qm_9%2BdyvEObJV3JP%2BhwwFj9%2Bgo%3DqusRVL7A%40mail.gmail.com.

Reply via email to