Illegal Behavior

Some operations in Zig trigger illegal behavior. This will come up in a lot of examples, so let’s take a look at it now.

Division by zero is illegal behavior:

const std = @import("std");
const print = std.debug.print;

pub fn main() void {
    print("{}\n", .{1 / 0});
}

The compiler detects it and prints an error:

$ zig build-exe illegal-behavior.zig
illegal-behavior.zig:5:25: error: division by zero here causes illegal behavior
    print("{}\n", .{1 / 0});
                        ^
[...]

The output shown here is edited a bit to remove irrelevant details.

Checked illegal behavior

The next example also does division by zero, but it’s a little less obvious:

const std = @import("std");
const print = std.debug.print;

fn f() u64 {
    return 0;
}

pub fn main() void {
    print("{}\n", .{1 / f()});
}

Now the compiler doesn’t detect it anymore:

$ zig build-exe illegal-behavior-2.zig

However, because division by zero is checked illegal behavior, it will still be caught at runtime:

$ ./illegal-behavior-2
thread 215181 panic: division by zero
[...]/illegal-behavior-2.zig:9:23: 0x11d7ed0 in main (illegal-behavior-2.zig)
    print("{}\n", .{1 / f()});
                      ^
[...]
Aborted

Unchecked illegal behavior

Going back to the previous example, let’s try to read an uninitialized variable:

const std = @import("std");
const print = std.debug.print;

pub fn main() void {
    const a: i64 = undefined;
    print("a = {}\n", .{a});
}

This is an example of unchecked illegal behavior, which causes unpredictable behavior:

$ zig build-exe illegal-behavior-3.zig
$ ./illegal-behavior-3
a = -6148914691236517206

Next example: Build Modes.