Unsafe Code

Overview

The unsafe package bypasses Go’s type safety. Use only when absolutely necessary for performance or interoperability.

unsafe.Pointer

import "unsafe"

// Convert between pointer types
var x int = 42
p := unsafe.Pointer(&x)
fp := (*float64)(p)  // Reinterpret as float64 pointer

Common Uses

Memory Layout

type Data struct {
    a int32
    b int64
}

fmt.Println(unsafe.Sizeof(Data{}))    // Size in bytes
fmt.Println(unsafe.Alignof(Data{}))   // Alignment
fmt.Println(unsafe.Offsetof(Data{}.b)) // Field offset

String to Bytes (Zero-Copy)

func stringToBytes(s string) []byte {
    return unsafe.Slice(unsafe.StringData(s), len(s))
}

Accessing Unexported Fields

// Not recommended, but possible
type hidden struct {
    secret int
}

h := hidden{secret: 42}
p := unsafe.Pointer(&h)
secretPtr := (*int)(p)
fmt.Println(*secretPtr)

Dangers

  • Not portable across platforms
  • May break with Go versions
  • Undefined behavior if misused
  • Bypasses garbage collector

Guidelines

  1. Avoid if possible - Use safer alternatives first
  2. Document thoroughly - Explain why unsafe is needed
  3. Isolate usage - Keep in small, well-tested functions
  4. Test extensively - Including on target platforms

Summary

Function Purpose
unsafe.Pointer Generic pointer type
unsafe.Sizeof Size in bytes
unsafe.Alignof Alignment requirement
unsafe.Offsetof Field offset