17 KiB
Selected Zig Built-in Functions Reference
Built-in functions are compiler intrinsics prefixed with @. Parameters marked comptime must be compile-time known. This is a practical reference to commonly used built-ins, not an exhaustive inventory; consult the language reference when completeness matters.
Table of Contents
- Type Conversions
- Integer/Float Operations
- Overflow Arithmetic
- Bit Manipulation
- Memory Operations
- Atomics
- Type Introspection
- Comptime Utilities
- SIMD/Vector
- C Interop
- Debug/Control Flow
Type Conversions
@as
@as(comptime T: type, expr) T
Safe type coercion. Preferred over explicit casts when conversion is unambiguous.
const x = @as(u32, 5); // comptime_int → u32
@intCast
@intCast(value: anytype) anytype
Convert between integer types. Runtime safety check if value doesn't fit.
const big: u64 = 100;
const small: u8 = @intCast(big); // OK if value fits
@floatCast
@floatCast(value: anytype) anytype
Convert between float types. Return type inferred.
const d: f64 = 3.14;
const f: f32 = @floatCast(d);
@intFromFloat
@intFromFloat(value: anytype) anytype
Float → integer. Truncates fractional part. Return type inferred.
const i: i32 = @intFromFloat(3.7); // i = 3
@floatFromInt
@floatFromInt(value: anytype) anytype
Integer → float. Return type inferred.
const f: f32 = @floatFromInt(42);
@intFromPtr
@intFromPtr(ptr: anytype) usize
Pointer → usize. For pointer arithmetic or FFI.
const addr: usize = @intFromPtr(&x);
@ptrFromInt
@ptrFromInt(addr: usize) anytype
usize → pointer. Return type inferred. Undefined behavior if invalid.
const ptr: *u32 = @ptrFromInt(0x1000);
@ptrCast
@ptrCast(ptr: anytype) anytype
Pointer type cast. Return type inferred.
const bytes: [*]u8 = @ptrCast(some_ptr);
@alignCast
@alignCast(ptr: anytype) anytype
Change pointer alignment. Safety check at runtime.
const aligned: *align(16) u8 = @alignCast(ptr);
@constCast
@constCast(ptr: anytype) anytype
Remove const qualifier from pointer. Return type inferred.
const mutable_ptr: *u32 = @constCast(const_ptr);
@volatileCast
@volatileCast(ptr: anytype) anytype
Remove volatile qualifier from pointer.
@bitCast
@bitCast(value: anytype) anytype
Reinterpret bits as different type. Sizes must match. Return type inferred.
const bits: u32 = @bitCast(@as(f32, 1.0));
const f: f32 = @bitCast(@as(u32, 0x3f800000));
@truncate
@truncate(value: anytype) anytype
Truncate integer to smaller type. Discards high bits. Return type inferred.
const small: u8 = @truncate(@as(u32, 0x12345678)); // 0x78
@intFromBool
@intFromBool(value: bool) u1
false → 0, true → 1.
const x: u8 = @intFromBool(true); // 1
@intFromEnum
@intFromEnum(value: anytype) anytype
Enum → backing integer type.
const State = enum(u8) { idle = 0, running = 1 };
const n: u8 = @intFromEnum(State.running); // 1
@enumFromInt
@enumFromInt(int: anytype) anytype
Integer → enum. Return type inferred.
const state: State = @enumFromInt(1); // State.running
@errorFromInt
@errorFromInt(int: anytype) anytype
Integer → error. Return type inferred.
@intFromError
@intFromError(err: anytype) std.meta.Int(.unsigned, @bitSizeOf(anyerror))
Error → integer.
@errorCast
@errorCast(err: anytype) anytype
Cast between error set types.
@addrSpaceCast
@addrSpaceCast(ptr: anytype) anytype
Convert pointer between address spaces (GPU/embedded).
Integer/Float Operations
@abs
@abs(value: anytype) anytype
Absolute value. Works on integers, floats, vectors.
const x = @abs(@as(i32, -5)); // 5
@min / @max
@min(a: T, b: T, ...) T
@max(a: T, b: T, ...) T
Return the minimum/maximum of two or more values.
const m = @max(3, 7); // 7
@divExact
@divExact(numerator: T, denominator: T) T
Exact division. Asserts no remainder.
const x = @divExact(10, 2); // 5
@divFloor
@divFloor(numerator: T, denominator: T) T
Floor division (rounds toward negative infinity).
const x = @divFloor(-7, 3); // -3
@divTrunc
@divTrunc(numerator: T, denominator: T) T
Truncating division (rounds toward zero).
const x = @divTrunc(-7, 3); // -2
@mod
@mod(numerator: T, denominator: T) T
Floor modulus. Result has same sign as denominator.
const x = @mod(-5, 3); // 1
@rem
@rem(numerator: T, denominator: T) T
Remainder. Result has same sign as numerator.
const x = @rem(-5, 3); // -2
Math Functions (floats/vectors)
@sqrt(x) // Square root
@sin(x) // Sine
@cos(x) // Cosine
@tan(x) // Tangent
@exp(x) // e^x
@exp2(x) // 2^x
@log(x) // Natural log
@log2(x) // Log base 2
@log10(x) // Log base 10
@floor(x) // Round down
@ceil(x) // Round up
@round(x) // Round to nearest
@trunc(x) // Truncate toward zero
@mulAdd(T, a, b, c) // Fused (a*b)+c
Overflow Arithmetic
Returns tuple: { result, overflow_bit } where overflow_bit is u1.
@addWithOverflow
@addWithOverflow(a: T, b: T) struct { T, u1 }
const result, const overflow = @addWithOverflow(@as(u8, 250), 10);
if (overflow != 0) { /* handle overflow */ }
@subWithOverflow
@subWithOverflow(a: T, b: T) struct { T, u1 }
@mulWithOverflow
@mulWithOverflow(a: T, b: T) struct { T, u1 }
@shlWithOverflow
@shlWithOverflow(a: T, b: Log2Int) struct { T, u1 }
Bit Manipulation
@clz
@clz(value: anytype) anytype
Count leading zeros.
const z = @clz(@as(u8, 0b00001111)); // 4
@ctz
@ctz(value: anytype) anytype
Count trailing zeros.
const z = @ctz(@as(u8, 0b11110000)); // 4
@popCount
@popCount(value: anytype) anytype
Count set bits (population count).
const c = @popCount(@as(u8, 0b10101010)); // 4
@byteSwap
@byteSwap(value: anytype) @TypeOf(value)
Reverse byte order (endianness conversion).
const swapped = @byteSwap(@as(u32, 0x12345678)); // 0x78563412
@bitReverse
@bitReverse(value: anytype) @TypeOf(value)
Reverse all bits.
const rev = @bitReverse(@as(u8, 0b11000001)); // 0b10000011
@shlExact / @shrExact
@shlExact(value: T, shift: Log2Int) T
@shrExact(value: T, shift: Log2Int) T
Shift with assertion that no bits are lost.
Memory Operations
@memcpy
@memcpy(dest: []T, src: []const T) void
Copy memory. Slices must not overlap.
@memcpy(dest[0..n], src[0..n]);
@memset
@memset(dest: []T, value: T) void
Fill memory with value.
@memset(buffer[0..n], 0);
@memmove
@memmove(dest: []T, src: []const T) void
Copy memory. Slices may overlap.
@sizeOf
@sizeOf(comptime T: type) comptime_int
Size of type in bytes (includes padding).
const size = @sizeOf(u32); // 4
@bitSizeOf
@bitSizeOf(comptime T: type) comptime_int
Size of type in bits.
const bits = @bitSizeOf(u24); // 24
@alignOf
@alignOf(comptime T: type) comptime_int
Alignment requirement of type.
const align = @alignOf(u64); // typically 8
@offsetOf
@offsetOf(comptime T: type, comptime field: []const u8) comptime_int
Byte offset of struct field.
const Point = struct { x: i32, y: i32 };
const off = @offsetOf(Point, "y"); // 4
@bitOffsetOf
@bitOffsetOf(comptime T: type, comptime field: []const u8) comptime_int
Bit offset of field (useful for packed structs).
Atomics
@atomicLoad
@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: AtomicOrder) T
Atomic read.
const val = @atomicLoad(u32, &counter, .acquire);
@atomicStore
@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: AtomicOrder) void
Atomic write.
@atomicStore(u32, &counter, 42, .release);
@atomicRmw
@atomicRmw(comptime T: type, ptr: *T, comptime op: AtomicRmwOp, operand: T, comptime ordering: AtomicOrder) T
Atomic read-modify-write. Returns previous value.
const old = @atomicRmw(u32, &counter, .Add, 1, .seq_cst);
Operations: .Add, .Sub, .And, .Or, .Xor, .Nand, .Min, .Max, .Xchg
@cmpxchgStrong / @cmpxchgWeak
@cmpxchgStrong(comptime T: type, ptr: *T, expected: T, new: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
@cmpxchgWeak(comptime T: type, ptr: *T, expected: T, new: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
Compare-and-swap. Returns null on success, old value on failure.
while (@cmpxchgWeak(u32, &counter, expected, new, .seq_cst, .seq_cst)) |actual| {
expected = actual;
}
Type Introspection
@TypeOf
@TypeOf(expr) type
Get type of expression at comptime.
const T = @TypeOf(some_value);
@typeInfo
@typeInfo(comptime T: type) std.builtin.Type
Get detailed type information.
const info = @typeInfo(MyStruct);
if (info == .@"struct") {
for (info.@"struct".fields) |field| {
// field.name, field.type, etc.
}
}
@Type - removed in Zig 0.16
@Type was removed in Zig 0.16. Use the specific type-construction builtin that matches the type you are creating:
Common replacements:
- integer type:
@Int(.signed, 32) - tuple type:
@Tuple(&.{ u32, []const u8 }) - pointer type:
@Pointer(...) - function type:
@Fn(...) - struct type:
@Struct(...) - union type:
@Union(...) - enum type:
@Enum(...) - opaque type: write
opaque {}directly
Keep @typeInfo for reflection; use the new builtins only when constructing types.
@typeName
@typeName(comptime T: type) [:0]const u8
Get string name of type.
const name = @typeName(u32); // "u32"
@hasDecl
@hasDecl(comptime T: type, comptime name: []const u8) bool
Check if type has declaration (const, fn, etc.).
if (@hasDecl(T, "init")) { T.init(); }
@hasField
@hasField(comptime T: type, comptime name: []const u8) bool
Check if struct/union has field.
@field
@field(value: anytype, comptime name: []const u8) anytype
Access field by comptime string name.
const x = @field(point, "x");
@FieldType
@FieldType(comptime T: type, comptime name: []const u8) type
Get type of a struct field.
@fieldParentPtr
@fieldParentPtr(comptime field_name: []const u8, field_ptr: anytype) anytype
Get pointer to containing struct from field pointer (for intrusive data structures).
const Node = struct { data: u32, hook: Hook };
fn getNode(hook: *Hook) *Node {
return @fieldParentPtr("hook", hook);
}
@tagName
@tagName(value: anytype) [:0]const u8
Get string name of enum/union tag.
const Color = enum { red, green, blue };
const name = @tagName(Color.red); // "red"
@errorName
@errorName(err: anyerror) [:0]const u8
Get string name of error.
const name = @errorName(error.OutOfMemory); // "OutOfMemory"
Comptime Utilities
@import
@import(comptime path: []const u8) type
Import module. Special: "std", "builtin".
const std = @import("std");
const builtin = @import("builtin");
const other = @import("other.zig");
@embedFile
@embedFile(comptime path: []const u8) *const [N:0]u8
Embed file contents as compile-time string.
const data = @embedFile("data.bin");
@compileError
@compileError(comptime msg: []const u8) noreturn
Emit compile error with message.
if (condition) @compileError("Invalid configuration");
@compileLog
@compileLog(args: ...) void
Print values at compile time for debugging.
@compileLog("x =", x, "T =", T);
@This
@This() type
Get enclosing struct/union/enum type.
const Self = @This();
fn method(self: *Self) void { ... }
@src
@src() std.builtin.SourceLocation
Get current source location (module, file, line, column, and function name).
@inComptime
@inComptime() bool
Check if currently executing at comptime.
if (@inComptime()) {
// comptime path
} else {
// runtime path
}
@setEvalBranchQuota
@setEvalBranchQuota(quota: u32) void
Increase comptime evaluation limit (default 1000).
@setEvalBranchQuota(100_000);
SIMD/Vector
@Vector
@Vector(len: comptime_int, T: type) type
Create SIMD vector type.
const Vec4f = @Vector(4, f32);
const v: Vec4f = .{ 1.0, 2.0, 3.0, 4.0 };
@splat
@splat(value: anytype) anytype
Create vector with all elements equal to value. Return type inferred.
const ones: @Vector(4, f32) = @splat(1.0);
@reduce
@reduce(comptime op: std.builtin.ReduceOp, value: anytype) ElementType
Reduce vector to scalar.
const sum = @reduce(.Add, vec); // sum all elements
const max = @reduce(.Max, vec); // find maximum
Operations: .Add, .Mul, .And, .Or, .Xor, .Min, .Max
@shuffle
@shuffle(T: type, a: @Vector(N, T), b: @Vector(N, T), mask: @Vector(M, i32)) @Vector(M, T)
Rearrange vector elements using mask.
const a: @Vector(4, i32) = .{ 1, 2, 3, 4 };
const b: @Vector(4, i32) = .{ 5, 6, 7, 8 };
const result = @shuffle(i32, a, b, .{ 0, 4, 1, 5 }); // {1, 5, 2, 6}
// Positive indices select from a, indices >= len select from b
@select
@select(T: type, pred: @Vector(N, bool), a: @Vector(N, T), b: @Vector(N, T)) @Vector(N, T)
Element-wise select: pred[i] ? a[i] : b[i].
C Interop
@cImport - deprecated migration path
@cImport(expr) type
Import C header files. In Zig 0.16 this is deprecated as the long-term API; prefer translating headers in build.zig with b.addTranslateC(...) and importing translate_c.createModule().
const c = @cImport({
@cDefine("_GNU_SOURCE", {});
@cInclude("stdio.h");
});
@cInclude
@cInclude(comptime path: []const u8) void
Include C header (inside @cImport).
@cDefine
@cDefine(comptime name: []const u8, value) void
Define C macro (inside @cImport).
@cUndef
@cUndef(comptime name: []const u8) void
Undefine C macro.
@extern
@extern(comptime T: type, options: ExternOptions) T
Declare external symbol.
@export
@export(target: anytype, options: ExportOptions) void
Export symbol. Takes pointer in 0.14.0+.
@export(&my_fn, .{ .name = "exported_name" });
C Varargs
@cVaStart() std.builtin.VaList // Start vararg processing
@cVaArg(*VaList, T) T // Get next vararg
@cVaCopy(*VaList) VaList // Copy vararg state
@cVaEnd(*VaList) void // End vararg processing
Debug/Control Flow
@branchHint
@branchHint(hint: std.builtin.BranchHint) void
Hint branch likelihood. Must be first statement in branch.
if (unlikely_condition) {
@branchHint(.cold);
// rarely executed
}
Hints: .none, .likely, .unlikely, .cold, .unpredictable
@breakpoint
@breakpoint() void
Insert debugger breakpoint.
@trap
@trap() noreturn
Crash immediately (illegal instruction).
@panic
@panic(msg: []const u8) noreturn
Trigger panic with message.
@setRuntimeSafety
@setRuntimeSafety(enabled: bool) void
Enable/disable safety checks in current scope.
@setRuntimeSafety(false);
// Unsafe operations here
@setFloatMode
@setFloatMode(mode: std.builtin.FloatMode) void
Set floating-point optimization mode.
@setFloatMode(.optimized); // Allow reordering, etc.
@returnAddress
@returnAddress() usize
Get return address of current function.
@frameAddress
@frameAddress() usize
Get frame pointer of current function.
@errorReturnTrace
@errorReturnTrace() ?*std.builtin.StackTrace
Get error return trace (if available).
@call
@call(modifier: std.builtin.CallModifier, fn: anytype, args: anytype) anytype
Call function with modifier.
const result = @call(.always_inline, my_fn, .{ arg1, arg2 });
Modifiers: .auto, .never_inline, .always_inline, .always_tail, .never_tail, .compile_time, .no_suspend. The .no_suspend modifier asserts that the call will not suspend.
@prefetch
@prefetch(ptr: anytype, options: PrefetchOptions) void
Prefetch memory into cache.
@prefetch(ptr, .{ .rw = .read, .locality = 3 });
WebAssembly
@wasmMemorySize
@wasmMemorySize(index: u32) u32
Get WebAssembly memory size in pages.
@wasmMemoryGrow
@wasmMemoryGrow(index: u32, delta: u32) u32
Grow WebAssembly memory by delta pages.
GPU/Workgroup
@workGroupId(dim: u32) u32 // Get workgroup ID
@workGroupSize(dim: u32) u32 // Get workgroup size
@workItemId(dim: u32) u32 // Get work item ID within group