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.zig
error: division by zero here causes illegal behavior
    print("{}\n", .{1 / 0});
                        ^

(The output shown here is edited to remove irrelevant details. When you run the examples yourself, it’ll be more verbose.)

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

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

$ ./checked 
panic: division by zero
checked.zig:9:23: in main
    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 unchecked.zig 
$ ./unchecked 
a = -6148914691236517206

Next example: Build Modes.