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.