Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reflect: UnsafePointer() map Values cannot be converted back to a map #70595

Closed
mhr3 opened this issue Nov 27, 2024 · 6 comments
Closed

reflect: UnsafePointer() map Values cannot be converted back to a map #70595

mhr3 opened this issue Nov 27, 2024 · 6 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.

Comments

@mhr3
Copy link

mhr3 commented Nov 27, 2024

Go version

go version go1.22.4 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
...

What did you do?

Obtained an unsafe.Pointer to a map like this:

m := map[string]any{"foo": "bar"}
uPtr := reflect.ValueOf(m).UnsafePointer()
...

// later I want to convert that unsafe.Pointer back into a map, but this isn't possible
rv := reflect.NewAt(reflect.TypeFor[map[string]any](), uPtr)
return rv.Interface().(*map[string]any)

What did you see happen?

The above snippet crashes the app, because uPtr is the actual map, not a pointer to it, and there's no other working API that can initialize/associate the Value with the uPtr. (or just cast the unsafe.Pointer into a map)

What did you expect to see?

There should be an operation analogous to Value.UnsafePointer() that can take the pointer and re-create a map out of it. Perhaps unsafe pkg itself should have Map methods similar to unsafe.Slice() + unsafe.SliceData()?

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Nov 27, 2024
@mhr3 mhr3 changed the title reflect: UnsafePointer() returns for map Values cannot be converted back to a map reflect: UnsafePointer() map Values cannot be converted back to a map Nov 27, 2024
@seankhliao
Copy link
Member

reflect.ValueOf(&m).UnsafePointer()

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Nov 27, 2024
@mhr3
Copy link
Author

mhr3 commented Nov 27, 2024

I'm aware there's other ways to do this, I'm opening an issue because doing things this way exposes an edge case that produces unusable pointers.

@randall77
Copy link
Contributor

You can do:

	var m map[string]any
	*(*unsafe.Pointer)(unsafe.Pointer(&m)) = uPtr

I agree that the interaction of unsafe and reflect isn't great. But then again, if you're using unsafe you don't normally need reflect.

@mhr3
Copy link
Author

mhr3 commented Nov 27, 2024

if you're using unsafe you don't normally need reflect.

Glad you bring that up - the pointer returned by reflect.ValueOf(m).UnsafePointer() is the actual map reference, which would be equivalent to unsafe.Pointer(m), but that's not valid, only unsafe.Pointer(&m) is. That's why I mentioned that perhaps the unsafe pkg should have special methods for maps.

@ianlancetaylor
Copy link
Member

I think we would need a very good reason to add anything map-specific to the unsafe package, more than just symmetry or cleanliness. That said, if you want to pursue this, file a proposal issue. See https://go.dev/s/proposal. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Projects
None yet
Development

No branches or pull requests

6 participants