# `std.debug`

### `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:

```zig
const std = @import("std");

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

`std.debug.print` takes two arguments:

```zig
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:

```zig
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:

```text
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:

```zig
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:

| Specifier | Meaning |
|---|---|
| `{d}` | Decimal integer |
| `{x}` | Hexadecimal integer |
| `{b}` | Binary integer |
| `{c}` | Character |
| `{s}` | String slice |
| `{any}` | Generic debug formatting |

A larger example:

```zig
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:

```text
decimal: 255
hex: ff
binary: 11111111
```

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

```zig
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:

```text
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`.

```zig
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`.

```zig
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.

