On Fri, Nov 25, 2022 at 12:06 AM Frédéric De Jaeger
<fdejae...@novaquark.com> wrote:
>
> Thanks for your reply.  I was really missing an essential piece.
> I found a bit weird that you need to write a helper to pass a uintptr to a 
> void* C function.  It could be nice to allow that
>
> func Foo(x uintptr) {
>     C.foo((*C.char)x)
> }
>
> but unfortunately, the compiler does not seem to accept it.  Is there a 
> reason ?

In Go you can't convert a uintptr to an arbitrary pointer.  You could
write C.foo((*C.char)(unsafe.Pointer(x))).  The compiler would accept
that, but it would break the unsafe.Pointer conversion rules.


> Anyway, I suppose the issue is that the runtime will interpret the uintptr, 
> when cast to a unsafe.Pointer as a potential valid pointer and if it looks a 
> bit too much like a legit go pointer, that might confuse the GC.  I suppose 
> that unsafe.Pointer can safely handle C pointers (from the doc of cgo)

Yes.

> If the uintptr contains a valid C pointer, do we have a practical  issue, 
> like with the following code ?
>
> func main() {
>    v := uintptr(unsafe.Pointer(C.CString("Hello from stdio")))
>    C.myprint(unsafe.Pointer(v))
>    C.free(unsafe.Pointer(cs))
> }
>
> This is a question about the current implementation, I know it violates the 
> rule of unsafe.Pointer.  This is just to have a better understanding about 
> what the runtime does and when (at conversion time?  C call time ? GC time ?)

Yes, if the pointer is a valid C pointer, then this kind of code is OK
in practice, though forbidden by the rules.

> From your last paragraph, can I do that ?
>
> /*
> #include <stdint.h>
> static void* IntToPtr(uintptr_t v) { return (void*)v; }
> */
> import "C"
>
> import (
>    "runtime/cgo"
>    "unsafe"
> )
>
> func HandleAsPointer(h cgo.Handle) unsafe.Pointer {
>    return C.IntToPtr(C.uintptr_t(uintptr(h)))
> }
>
> Here the cast int -> void* happens in the C world and the conversion back to 
> unsafe.Pointer looks legit according to the rule of cgo.  But this will 
> create an unsafe.Pointer containing a totally invalid pointer.  Will it work 
> (practically and theoretically) ?  Is the GC robust against the presence of a 
> random value in an unsafe.Pointer ?

This won't work.  As you say, the GC can't handle an invalid pointer
value that is marked as a pointer.

Ian

-- 
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/CAOyqgcXvqaxav7djL0obMGurT-Y8RaMLxbRndRQ9jKVRN2C_qg%40mail.gmail.com.

Reply via email to