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.