On Tue, Jul 18, 2023 at 5:22 PM Jochen Voss <jochen.v...@gmail.com> wrote:

> Dear Jason,
>
> Thanks for the idea of using reflect.  Do you know whether
> `reflect.ValueOf(a).UnsafePointer()` is somehow "safer" than
> `*(*uintptr)(unsafe.Pointer(&a))`?
>

For what it's worth: I'd argue comparing
`reflect.ValueOf(a).UnsafePointer()` provides stronger guarantees of
portability and correctness than comparing
`*(*uintptr)(unsafe.Pointer(&a))`. Also, you should probably use
`*(*unsafe.Pointer)(unsafe.Pointer(&a))` if anything. It does the same
thing, when it works, but I'm not sure that the conversion to `uintptr`
that is happening is guaranteed to work under a moving GC. A comparison
isn't necessarily arithmetic <https://pkg.go.dev/unsafe#Pointer> - and
those rules are just what `gc` is specifying anyways, an implementation is
free to choose others, in theory.

That's because the latter relies on maps being "pointer-shaped". In theory,
an implementation might not represent a map as a plain pointer. Though I
admittedly having trouble coming up with an alternative design.

Plus, the documentation <https://pkg.go.dev/reflect#Value.UnsafePointer> of
`reflect.Value.UnsafePointer` *also* doesn't really say *what* the returned
pointer is for a map and what its semantics are. But it seems somewhat
safer to assume that an implementation that would *not* represent a map as
a plain pointer, would implement `reflect.Value.UnsafePointer` in a way
that still allowed you to compare them for identity purposes.

But, as you might be able to tell, all of this is a bit of a nitpick of how
willing you are to make assumptions about reasonable ways an implementation
might deviate from what they *have* to do. I'm pretty sure there is no way
to compare map values that is keeping *strictly* in the bounds of
well-defined behavior. I would, personally, feel comfortable using either
and to just assume that I never have to run my code in a sufficiently wild
implementation. And I'd probably try to benchmark/test if the `reflect`
based version changes performance characteristics (I would assume it makes
it easier for the map to escape, but maybe maps *always* escape anyways)
and if not, use `reflect`.


> reflect.DeepEqual will not work, since it just compares contents of the
> maps: https://go.dev/play/p/tE_qZI2cKEd
>
> All the best,
> Jochen
> On Tuesday, 18 July 2023 at 15:52:24 UTC+1 Jason Phillips wrote:
>
>> You can also use the reflect package rather than (directly) reaching for
>> unsafe. The reflect.DeepEqual function does something along the lines of:
>> https://go.dev/play/p/IVt0Z-mxugh
>>
>> On Tuesday, July 18, 2023 at 10:45:18 AM UTC-4 Jan Mercl wrote:
>>
>>> On Tue, Jul 18, 2023 at 4:35 PM Jochen Voss <joche...@gmail.com> wrote:
>>>
>>> > Is there a better way?
>>>
>>> I have never been here and please don't do this:
>>> https://go.dev/play/p/x4QYJubXMnQ
>>>
>> --
> 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/30202b52-554e-462e-aaa4-dfe7f4d23554n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/30202b52-554e-462e-aaa4-dfe7f4d23554n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAEkBMfGSn7D4My8HgW97RZ95kdDH-2UFUasQS9R87aN--ZGJ%2BQ%40mail.gmail.com.

Reply via email to