Skip to content

`std.debug`

The std.debug module contains utilities for debugging programs. The most commonly used function is print, which writes formatted output to standard error.

std.debug

The std.debug module contains utilities for debugging programs. The most commonly used function is print, which writes formatted output to standard error.

A small example:

const std = @import("std");

pub fn main() void {
    std.debug.print("hello, zig\n", .{});
}

std.debug.print takes two arguments:

std.debug.print(format, values);

The first argument is a format string. The second is a tuple containing values to insert into the format string.

For example:

const std = @import("std");

pub fn main() void {
    const name = "zig";
    const year = 2026;

    std.debug.print("{s} {d}\n", .{ name, year });
}

The output is:

zig 2026

{s} prints a string slice.

{d} prints a decimal integer.

The formatting language is checked at compile time. If the format string and arguments do not match, the compiler reports an error.

For example:

const std = @import("std");

pub fn main() void {
    const value = 42;

    std.debug.print("{s}\n", .{value});
}

This fails because {s} expects string data, not an integer.

Formatting errors are detected before the program runs.

The formatting system supports many value types:

SpecifierMeaning
{d}Decimal integer
{x}Hexadecimal integer
{b}Binary integer
{c}Character
{s}String slice
{any}Generic debug formatting

A larger example:

const std = @import("std");

pub fn main() void {
    const number: u8 = 255;

    std.debug.print("decimal: {d}\n", .{number});
    std.debug.print("hex: {x}\n", .{number});
    std.debug.print("binary: {b}\n", .{number});
}

The output is:

decimal: 255
hex: ff
binary: 11111111

{any} asks Zig to print a debug representation of a value.

const std = @import("std");

const Point = struct {
    x: i32,
    y: i32,
};

pub fn main() void {
    const p = Point{
        .x = 3,
        .y = 5,
    };

    std.debug.print("{any}\n", .{p});
}

The output is similar to:

main.Point{ .x = 3, .y = 5 }

This is useful while debugging programs.

std.debug.print writes to standard error, not standard output. This allows diagnostic messages to remain separate from normal program output.

The function is intended mainly for debugging and small utilities. Programs that need structured output usually use writers from the I/O library directly.

A helper function often used with std.debug is std.debug.assert.

const std = @import("std");

pub fn main() void {
    const value = 10;

    std.debug.assert(value > 0);
}

If the condition is false, the program stops immediately.

Assertions help detect programming mistakes early.

Another common utility is std.debug.panic.

const std = @import("std");

pub fn main() void {
    std.debug.panic("fatal error\n", .{});
}

This prints a message and terminates the program.

Unlike many languages, Zig does not hide stack traces behind runtime machinery. Debug information is treated as part of normal systems programming.

Exercise 14-1. Print an integer in decimal, hexadecimal, and binary.

Exercise 14-2. Define a struct and print it with {any}.

Exercise 14-3. Write a program that uses std.debug.assert.

Exercise 14-4. Modify a program so debugging messages go through std.debug.print while normal output uses standard output.