# Release Modes

### Release Modes

Zig can build the same source code in different optimization modes.

The mode controls speed, size, safety checks, and debug information.

The four common modes are:

| Mode | Main purpose |
|---|---|
| `Debug` | Fast compilation, safety checks, useful debug info |
| `ReleaseSafe` | Optimized code with safety checks |
| `ReleaseFast` | Optimized code for speed |
| `ReleaseSmall` | Optimized code for small size |

With `zig build-exe`, the default is `Debug`.

```sh
zig build-exe main.zig
```

To select a release mode, use `-O`:

```sh
zig build-exe main.zig -O Debug
zig build-exe main.zig -O ReleaseSafe
zig build-exe main.zig -O ReleaseFast
zig build-exe main.zig -O ReleaseSmall
```

In `Debug`, Zig keeps runtime safety checks.

For example, this program indexes past the end of an array:

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

pub fn main() void {
    const a = [_]u8{ 1, 2, 3 };
    const i: usize = 9;

    std.debug.print("{d}\n", .{a[i]});
}
```

In a checked mode, this is caught as a safety problem.

Safety checks include bounds checks, integer overflow checks, invalid enum values, invalid error values, and other operations that Zig can guard at runtime.

`ReleaseSafe` keeps safety checks but optimizes the program.

```sh
zig build-exe main.zig -O ReleaseSafe
```

This is useful for production programs where correctness diagnostics are more important than the last measure of speed.

`ReleaseFast` optimizes for speed and disables many runtime safety checks.

```sh
zig build-exe main.zig -O ReleaseFast
```

This mode is appropriate only when the program has been tested enough that unchecked operations are acceptable.

`ReleaseSmall` optimizes for size.

```sh
zig build-exe main.zig -O ReleaseSmall
```

This is useful for embedded programs, WebAssembly, small command-line tools, and places where binary size matters.

The selected mode is visible at compile time:

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

pub fn main() void {
    std.debug.print("mode = {s}\n", .{@tagName(builtin.mode)});
}
```

This can be used to choose different behavior.

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

pub fn expensiveCheck() bool {
    if (builtin.mode == .Debug or builtin.mode == .ReleaseSafe) {
        return true;
    } else {
        return false;
    }
}
```

Use this sparingly. Most code should not change behavior based on optimization mode.

A better use is diagnostics:

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

pub fn trace(comptime fmt: []const u8, args: anytype) void {
    if (builtin.mode == .Debug) {
        std.debug.print(fmt, args);
    }
}
```

In `Debug`, `trace` prints. In release builds, it does nothing.

Build mode is also part of the standard `build.zig` pattern:

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

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "main",
        .root_module = b.createModule(.{
            .root_source_file = b.path("main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });

    b.installArtifact(exe);
}
```

Then the mode is chosen from the command line:

```sh
zig build -Doptimize=Debug
zig build -Doptimize=ReleaseSafe
zig build -Doptimize=ReleaseFast
zig build -Doptimize=ReleaseSmall
```

The build file describes the program. The command line selects how it is built.

A good rule is:

```text
Debug while writing.
ReleaseSafe while testing serious builds.
ReleaseFast when speed has been measured.
ReleaseSmall when size has been measured.
```

Do not choose a release mode by habit. Choose it for the property you need.

Exercise 17-21. Print `builtin.mode` in each optimization mode.

Exercise 17-22. Write an array bounds error and compare `Debug` with `ReleaseFast`.

Exercise 17-23. Write a `trace` function that prints only in `Debug`.

Exercise 17-24. Build the same program with `ReleaseFast` and `ReleaseSmall`, then compare file sizes.

