Description
What version of Go are you using (go version
)?
$ go version go version go1.15.8 linux/amd64
Does this issue reproduce with the latest release?
N/A, bug report is for x/sys/windows
What did you do?
I'm writing a library to manipulate the Windows firewall at inet.af/wf. As part of calling the API, I need to construct a tree of C structs with various pointer unsafeties within. I'm using windows.LocalAlloc
and windows.LocalFree
to allocate memory on the non-go-managed heap.
Unfortunately though, windows.LocalAlloc
returns the pointer as a uintptr - presumably because LocalAlloc
can return either a raw pointer or a Windows handle to movable memory. This means that any time I want to use the allocated memory, I have to do an unsafe conversion that makes go vet
mad:
type myStruct { ... }
mem, err := windows.LocalAlloc(windows.LPTR, uint32(unsafe.Sizeof(myStruct{})))
if err != nil {
panic(err)
}
ret := (*myStruct)(unsafe.Pointer(mem))
Even though these are famous last words, I believe that this unsafe conversion is actually safe, because the uintptr isn't representing a pointer into the Go heap. It would be nice to be able to use LocalAlloc
without triggering a false positive in go vet
.
The two ways I can think of to achieve this are:
- Make
LocalAlloc
return anunsafe.Pointer
instead of auintptr
, to express that it can be cast to whatever pointer type you wish, subject to unsafety rules. That includes converting it to a uintptr, which is the underlying type of windows.Handle, for the case where you allocate a movable chunk of memory. - Break
LocalAlloc
into two functions, one returning an unsafe.Pointer for fixed allocs, and one returning a windows.Handle for movable allocs. That would make it easier to use movable allocs in Go (although I cannot think why you'd want to, so my preference would be for the prior option).