> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go uintptr

`uintptr` is a built-in, platform-dependent unsigned integer type in Go designed specifically to be large enough to hold the bit pattern of any memory address (pointer). On a 32-bit architecture, `uintptr` is 4 bytes; on a 64-bit architecture, it is 8 bytes.

Unlike standard typed pointers (e.g., `*int`), `uintptr` is strictly an integer value. It represents the raw numeric address of a memory location and supports standard integer arithmetic operations, which Go's standard pointers strictly prohibit.

## The Conversion Bridge and Arithmetic Rules

Go's type system does not allow direct conversion between typed pointers and `uintptr`. The `unsafe.Pointer` type acts as the mandatory intermediary bridge.

When performing pointer arithmetic using `uintptr`, two strict rules apply:

1. **Single Expression:** The conversion from `unsafe.Pointer` to `uintptr`, the arithmetic operation, and the conversion back to `unsafe.Pointer` must be executed as a single expression. Storing an intermediate `uintptr` in a variable is invalid because it allows the garbage collector to run between statements, potentially moving or reclaiming the underlying memory before the arithmetic is complete.
2. **Allocation Boundaries:** The result of the arithmetic must point into the same allocated object (e.g., advancing from one index of an array to another). Advancing a pointer past the end of its allocated object results in undefined behavior. Furthermore, offsets must be calculated dynamically using `unsafe.Sizeof()` or `unsafe.Offsetof()` to account for platform-dependent type sizes.

```go theme={"dark"}
package main

import "unsafe"

func main() {
	// Allocate an array to ensure pointer arithmetic stays within the same object
	arr := [2]int{10, 20}
	p := &arr[0]

	// VALID: Conversion and arithmetic performed in a single expression.
	// 1. p (*int) -> unsafe.Pointer
	// 2. unsafe.Pointer -> uintptr
	// 3. Add dynamic byte offset using unsafe.Sizeof to remain platform-safe
	// 4. uintptr -> unsafe.Pointer
	// 5. unsafe.Pointer -> *int
	nextPtr := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(arr[0])))
	
	_ = nextPtr
}
```

## Garbage Collection Semantics

The most critical technical characteristic of `uintptr` is its general invisibility to the Go Garbage Collector (GC).

Because the runtime treats `uintptr` purely as an integer, it does not register it as a live reference to the underlying memory. This introduces two strict memory management implications:

1. **Unreachability:** If an allocated object is referenced only by a `uintptr` variable, the GC considers the object unreachable and will reclaim its memory. The `uintptr` will then hold a dangling, invalid memory address.
2. **Memory Relocation:** Go's runtime dynamically manages memory, which includes moving goroutine stacks (stack shrinking and growing). When the runtime moves a variable to a new memory location, it automatically updates all typed pointers (`*T`) and `unsafe.Pointer` references pointing to that variable. It will **not** update a `uintptr`.

## Compiler Exceptions for GC Invisibility

There are two critical, built-in compiler exceptions where the Go runtime temporarily protects the memory associated with a `uintptr` from being moved or reclaimed. Both require strict adherence to inline conversion rules.

### 1. Syscall and Assembly Arguments

When a `uintptr` is passed as an argument to an assembly function (most notably `syscall.Syscall`), the Go compiler specifically recognizes this pattern and implicitly keeps the underlying object alive and pinned in memory for the duration of the call.

This exception **only applies if the conversion occurs directly inline within the argument list**. If the pointer is converted to a `uintptr` and stored in a variable beforehand, the compiler will not recognize the pattern.

```go theme={"dark"}
//go:build linux

package main

import (
	"syscall"
	"unsafe"
)

func main() {
	var data [8]byte
	fd := uintptr(0) // stdin

	// VALID: The compiler recognizes the inline conversion and protects 'data'.
	// SYS_READ expects a file descriptor, a buffer memory address, and a length.
	syscall.Syscall(syscall.SYS_READ, fd, uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)))

	// INVALID: The compiler does not recognize this pattern. 
	// The GC may move or reclaim 'data' before the syscall executes.
	u := uintptr(unsafe.Pointer(&data[0]))
	syscall.Syscall(syscall.SYS_READ, fd, u, uintptr(len(data)))
}
```

### 2. The `reflect` Package

Methods in the `reflect` package, specifically `reflect.Value.Pointer()` and `reflect.Value.UnsafeAddr()`, return a `uintptr` rather than an `unsafe.Pointer` to prevent callers from mutating memory without explicitly importing the `unsafe` package.

To prevent the GC from reclaiming the memory immediately after the method returns, the compiler mandates that the `uintptr` result must be converted to `unsafe.Pointer` **immediately within the same expression**.

```go theme={"dark"}
package main

import (
	"reflect"
	"unsafe"
)

func main() {
	var v int
	val := reflect.ValueOf(&v)

	// VALID: Immediate conversion in the same expression protects the memory.
	p := unsafe.Pointer(val.Pointer())

	// INVALID: Storing the uintptr before conversion breaks compiler protection.
	// The GC may reclaim or move 'v' before the conversion to unsafe.Pointer.
	u := val.Pointer()
	p2 := unsafe.Pointer(u)

	_, _ = p, p2
}
```

## Type Hierarchy and Memory Safety

To understand `uintptr`, it must be placed within Go's memory reference hierarchy:

* **`*T` (Typed Pointer):** Memory-safe, tracked by the GC, strictly typed, no direct arithmetic allowed.
* **`unsafe.Pointer`:** Memory-unsafe, tracked by the GC, untyped (can cast to/from any `*T`), arithmetic allowed via the `unsafe.Add` function (introduced in Go 1.17 as a safer alternative to `uintptr` math).
* **`uintptr`:** Memory-unsafe, **not** tracked by the GC (excluding the specific inline compiler exceptions), integer type lacking pointer semantics, standard integer arithmetic allowed.

Converting a pointer to a `uintptr` strips away all memory-safety guarantees and lifecycle tracking provided by the Go runtime, reducing the reference to a volatile, static integer snapshot of a memory address at a specific point in time.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Go Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
