Zig Comptime Cheat Sheet
Covers Zig's comptime keyword, compile-time function execution, generic types via comptime parameters, and comptime reflection with @TypeOf/@typeInfo.
`comptime` Values & Blocks
`comptime` forces an expression to be evaluated at compile time, with a normal Zig block/expression syntax.
const std = @import("std");fn fibonacci(n: u32) u32 { if (n < 2) return n; return fibonacci(n - 1) + fibonacci(n - 2);}pub fn main() void { // computed entirely at compile time, baked into the binary const result = comptime fibonacci(10); std.debug.print("fib(10) = {}\n", .{result}); comptime { // arbitrary compile-time logic block var sum: u32 = 0; var i: u32 = 0; while (i < 5) : (i += 1) sum += i; }}
Generics via `comptime` Parameters
Zig has no separate generics syntax — types are just comptime-known values passed as parameters.
fn max(comptime T: type, a: T, b: T) T { return if (a > b) a else b;}const m = max(i32, 3, 7); // T = i32const f = max(f64, 1.5, 2.25); // T = f64// Generic container: a function returning a typefn Stack(comptime T: type) type { return struct { items: std.ArrayList(T), pub fn init(allocator: std.mem.Allocator) @This() { return .{ .items = std.ArrayList(T).init(allocator) }; } pub fn push(self: *@This(), value: T) !void { try self.items.append(value); } };}const IntStack = Stack(i32);
Compile-Time Reflection
`@TypeOf`, `@typeInfo`, and `@field` let you inspect and generate code based on types.
const std = @import("std");fn printFields(value: anytype) void { const T = @TypeOf(value); const info = @typeInfo(T); inline for (info.Struct.fields) |field| { std.debug.print("{s}: {any}\n", .{ field.name, @field(value, field.name) }); }}const Point = struct { x: i32, y: i32 };pub fn main() void { printFields(Point{ .x = 1, .y = 2 }); // x: 1 // y: 2}
Comptime-Known Arrays & `inline for`
Build lookup tables and unroll loops entirely at compile time.
fn buildSquares(comptime n: usize) [n]u32 { var table: [n]u32 = undefined; for (&table, 0..) |*slot, i| { slot.* = @as(u32, @intCast(i * i)); } return table;}const squares = comptime buildSquares(10); // computed at compile timepub fn main() void { // inline for unrolls the loop at compile time (n must be comptime-known) inline for (squares) |sq| { @import("std").debug.print("{} ", .{sq}); }}
Comptime-Related Builtins & Keywords
Reference for the core compile-time toolbox.
- comptime- forces an expression, parameter, or var to be known/evaluated at compile time
- @TypeOf(x)- returns the type of an expression, itself a comptime value
- @typeInfo(T)- returns a struct describing T's fields/kind for reflection
- @field(obj, name)- accesses a field by comptime-known string name
- inline for / inline while- unrolls loops at compile time; bounds must be comptime-known
- anytype- parameter type inferred per call site, resolved at compile time
- @compileError(msg)- aborts compilation with a custom message, used for comptime validation
Use comptime parameters plus @compileError to validate generic type constraints at the top of a function (e.g. "T must be an integer type") — you get a clear, custom compiler error instead of a confusing failure deep inside the function body.