Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Zig Dictionary
  3. comptime (Compile-time Evaluation)

comptime (Compile-time Evaluation)

The comptime keyword in Zig allows computations that would normally occur at runtime to be evaluated at compile time. Resolving values at compile time enables binary size reduction, improved execution speed, and type-level programming. This page covers the basic usage and behavior of comptime.

Syntax

// -----------------------------------------------
// comptime variable — a constant evaluated at compile time
// -----------------------------------------------

comptime var name: Type = expression;
// name       : identifier for the compile-time variable
// Type       : a type that is known at compile time
// expression : an expression that can be evaluated at compile time

// -----------------------------------------------
// comptime function argument — an argument whose value is resolved at compile time
// -----------------------------------------------

fn funcName(comptime argName: Type) ReturnType {
    // comptime arguments are resolved at compile time,
    // so they can be used as type parameters
}

// -----------------------------------------------
// comptime block — a block executed at compile time
// -----------------------------------------------

comptime {
    // All expressions inside this block are evaluated at compile time.
    // Use this for compile-time assertions and type checks.
}

// -----------------------------------------------
// comptime expression — evaluates a single expression at compile time
// -----------------------------------------------

const constName = comptime expression;
// Binds the result of the expression as a compile-time constant.

Syntax Overview

Syntax / KeywordDescription
comptime var x = exprDeclares a variable that is evaluated and resolved at compile time.
comptime exprForces a single expression to be evaluated at compile time.
comptime { ... }Runs all code inside the block at compile time. Used for type checks and assertions.
fn f(comptime T: type)Defines a generic function that accepts a type as a compile-time argument.
fn f(comptime n: usize)Accepts a value such as an integer as a compile-time argument. Useful for specifying array sizes.
@TypeOf(expr)Retrieves the type of an expression at compile time. Often used together with comptime.
@typeInfo(Type)Retrieves type information (fields, tags, etc.) at compile time.
@compileError("message")Raises an error at compile time. Useful for detecting invalid type arguments.
@compileLog(value)Outputs a debug log at compile time.

Sample Code

comptime_basic.zig
// comptime_basic.zig — demonstrates basic usage of comptime
// Uses character data from KOF (The King of Fighters) to show
// compile-time computation, comptime function arguments, and comptime blocks.

const std = @import("std");

// -----------------------------------------------
// comptime constants — define constants resolved at compile time
// -----------------------------------------------

// Defines the team size as a compile-time constant.
// While const alone may sometimes result in a runtime constant,
// literal values like these are automatically resolved at compile time.
const TEAM_SIZE: usize = 3;
const MAX_POWER: u32 = 9999;

// -----------------------------------------------
// Function with comptime argument — accepts a type as a compile-time parameter
// -----------------------------------------------

// Using comptime T: type lets you create a generic function that takes a type as a parameter.
// This function determines the array element count at compile time.
fn makeTeam(comptime size: usize, init_power: u32) [size]u32 {
    // size is resolved at compile time, so it can be used directly as an array size.
    var team: [size]u32 = undefined;
    var i: usize = 0;
    while (i < size) : (i += 1) {
        team[i] = init_power;
    }
    return team;
}

// Returns the maximum value for the given type, received as a comptime argument.
fn maxValue(comptime T: type) T {
    // @typeInfo() retrieves type information at compile time.
    return std.math.maxInt(T);
}

// -----------------------------------------------
// comptime block — runs assertions at compile time
// -----------------------------------------------

// Performs compile-time checks using a comptime block.
// If a condition is false, a compile error is raised.
comptime {
    // Ensures TEAM_SIZE is greater than 0 at compile time.
    std.debug.assert(TEAM_SIZE > 0);
    // Ensures MAX_POWER is within the range of u32.
    std.debug.assert(MAX_POWER <= std.math.maxInt(u32));
}

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.print("=== KOF comptime sample ===\n\n", .{});

    // -----------------------------------------------
    // Using comptime constants
    // -----------------------------------------------

    // Uses compile-time constants directly.
    // TEAM_SIZE is embedded as 3 at compile time.
    try stdout.print("Team size  (comptime const): {d}\n", .{TEAM_SIZE});
    try stdout.print("Max power  (comptime const): {d}\n\n", .{MAX_POWER});

    // -----------------------------------------------
    // Calling a function with a comptime argument
    // -----------------------------------------------

    // The first argument to makeTeam is a comptime argument, so a literal is passed.
    // The returned array type is also resolved to [3]u32 at compile time.
    var heroTeam = makeTeam(TEAM_SIZE, 5000);

    // Sets the power values for the "hero team" from KOF.
    heroTeam[0] = 8500; // Kusanagi Kyo
    heroTeam[1] = 8200; // Terry Bogard
    heroTeam[2] = 7800; // Mai Shiranui

    const heroNames = [TEAM_SIZE][]const u8{
        "Kusanagi Kyo",
        "Terry Bogard",
        "Mai Shiranui",
    };

    try stdout.print("--- Hero Team Power ---\n", .{});
    for (heroNames, heroTeam) |name, power| {
        try stdout.print("  {s}: {d}\n", .{ name, power });
    }
    try stdout.print("\n", .{});

    // -----------------------------------------------
    // comptime expression — evaluates an expression at compile time
    // -----------------------------------------------

    // The comptime keyword forces the expression to be evaluated at compile time.
    // The result is treated as a compile-time constant.
    const rivalTeamSize = comptime TEAM_SIZE + 2; // 5-person team
    try stdout.print("Rival team size (comptime expr): {d}\n\n", .{rivalTeamSize});

    // -----------------------------------------------
    // maxValue() — example of using a comptime type argument
    // -----------------------------------------------

    // Passes a type as a compile-time argument.
    // The maximum value for each type is computed at compile time.
    const maxU8 = maxValue(u8);
    const maxU16 = maxValue(u16);
    const maxU32 = maxValue(u32);

    try stdout.print("--- Max values by type (comptime type arg) ---\n", .{});
    try stdout.print("  u8  max: {d}\n", .{maxU8});
    try stdout.print("  u16 max: {d}\n", .{maxU16});
    try stdout.print("  u32 max: {d}\n", .{maxU32});
    try stdout.print("\n", .{});

    // -----------------------------------------------
    // @TypeOf() — retrieves the type at compile time
    // -----------------------------------------------

    const kyo_power: u32 = 8500;
    const iori_power: i32 = -9000; // Yagami Iori (negative value)

    // @TypeOf() returns the type of a variable at compile time.
    const KyoType = @TypeOf(kyo_power);
    const IoriType = @TypeOf(iori_power);

    try stdout.print("--- Compile-time type retrieval with @TypeOf() ---\n", .{});
    try stdout.print("  Kyo power type:  {s}\n", .{@typeName(KyoType)});
    try stdout.print("  Iori power type: {s}\n", .{@typeName(IoriType)});
    try stdout.print("\n", .{});

    // -----------------------------------------------
    // comptime loop — a loop unrolled at compile time
    // -----------------------------------------------

    // inline for unrolls the loop at compile time.
    // Each iteration is generated as individual code.
    const kofTeams = [_][]const u8{
        "Kusanagi Kyo",
        "Terry Bogard",
        "Mai Shiranui",
        "Yagami Iori",
        "Ralf Jones",
    };

    try stdout.print("--- KOF Fighter Roster ---\n", .{});
    inline for (kofTeams, 0..) |fighter, idx| {
        // idx in inline for is treated as a compile-time constant.
        try stdout.print("  [{d}] {s}\n", .{ idx + 1, fighter });
    }

    try stdout.print("\ncomptime verification complete.\n", .{});
}
zig run comptime_basic.zig
=== KOF comptime sample ===

Team size  (comptime const): 3
Max power  (comptime const): 9999

--- Hero Team Power ---
  Kusanagi Kyo: 8500
  Terry Bogard: 8200
  Mai Shiranui: 7800

Rival team size (comptime expr): 5

--- Max values by type (comptime type arg) ---
  u8  max: 255
  u16 max: 65535
  u32 max: 4294967295

--- Compile-time type retrieval with @TypeOf() ---
  Kyo power type:  u32
  Iori power type: i32

--- KOF Fighter Roster ---
  [1] Kusanagi Kyo
  [2] Terry Bogard
  [3] Mai Shiranui
  [4] Yagami Iori
  [5] Ralf Jones

comptime verification complete.

Details

comptime is a keyword in Zig that explicitly instructs the compiler to evaluate something at compile time. While a normal program computes values at runtime, adding comptime causes expressions, variables, and function arguments to be evaluated during compilation. The precomputed values are embedded directly into the binary, resulting in zero runtime overhead.

Writing comptime T: type as a function argument lets you create a generic function that accepts a type as a parameter. Calling it as maxValue(u8) or maxValue(u32) causes type-specific code to be generated at compile time. The same applies when using a comptime argument for an array size — it can be used as part of the return type, such as [size]u32.

A comptime { ... } block serves as a place to write assertions and type checks that run at compile time. Combined with @compileError(), you can detect invalid arguments at compile time. inline for unrolls a loop at compile time and treats each iteration's index as a compile-time constant.

@TypeOf() is a built-in function that retrieves the type of a variable or expression at compile time. The retrieved type can be printed as a string with @typeName() or passed to other comptime operations. When detailed type information is needed, refer to @typeInfo() as well. For more advanced generic programming with types, see Generics. For combining comptime with error handling, see Error Handling.

If you find any errors or copyright issues, please .