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.