What's the difference between *uint and uintptr in Golang?
The short answer is "never use uintptr
".
The long answer is that uintptr
is there to bypass the type system and allow the Go implementors to write Go runtime libraries, including the garbage collection system, in Go, and to call C-callable code including system calls using C pointers that are not handled by Go at all.
If you're acting as an implementor—e.g., providing access to system calls on a new OS—you'll need uintptr
. You will also need to know all the special magic required to use it, such as locking your goroutine to an OS-level thread if the OS is going to do stack-ish things to OS-level threads, for instance. (If you're using it with Go pointers, you may also need to tell the compiler not to move your goroutine stack, which is done with special compile-time directives.)
Edit: as kostix notes in a comment, the runtime system considers an unsafe.Pointer
as a reference to an object, which keeps the object alive for GC. It does not consider a uintptr
as such a reference. (That is, while unsafe.Pointer
has a pointer type, uintptr
has integer type.) See also the documentation for the unsafe
package.
uintptr is simply an integer representation of a memory address, regardless of the actual type it points to. Sort of like void *
in C, or just casting a pointer to an integer. It's purpose is to be used in unsafe black magic, and it is not used in everyday go code.
You are conflating uintptr and *uint. uintptr is used when you're dealing with pointers, it is a datatype that is large enough to hold a pointer. It is mainly used for unsafe memory access, look at the unsafe package. *uint is a pointer to an unsigned integer.