FYI, filed https://github.com/golang/go/issues/68086 for the spec-hole that
conversions between unsafe.Pointer and other pointer types are not
implementation defined.

On Thu, 20 Jun 2024 at 14:12, Axel Wagner <axel.wagner...@googlemail.com>
wrote:

>
>
> 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/CAEkBMfGEJivxGLb6iEWMri0Szesf8EgVwR%2BV9CVCbv0rRvo15Q%40mail.gmail.com.

Reply via email to