# Runtime Safety

> Checked illegal behaviour, and where the checks go.

Zig inserts runtime checks for a class of mistakes that C leaves undefined:
out-of-bounds indexing, integer overflow, invalid casts, unwrapping a null
optional, and more. When a check fails the program panics with a clear message
instead of quietly reading whatever came next in memory.

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

pub fn main(init: std.process.Init) !void {
    _ = init;

    // Zig inserts checks for out-of-bounds access, integer overflow, invalid
    // casts, and more. In a safety-enabled build this panics with
    // "index out of bounds" rather than reading whatever memory follows.
    const array = [_]u8{ 1, 2, 3 };
    var index: usize = 5;
    _ = &index; // defeat comptime evaluation
    const value = array[index];
    std.debug.print("never printed: {d}\n", .{value});
}

// This snippet is marked `//! norun` because it deliberately panics: CI
// compiles it to prove the code is still valid, but does not execute it.
```

*Deliberately panics. Compiled by CI to prove it is still valid, but not executed. (`02-language.runtime-safety`)*

## Safety depends on the build mode

| Mode | Safety checks | Optimised |
| --- | --- | --- |
| `Debug` | yes | no |
| `ReleaseSafe` | yes | yes |
| `ReleaseFast` | **no** | yes |
| `ReleaseSmall` | **no** | yes |

This is the decision C never gives you explicitly. `ReleaseSafe` keeps the
checks and is a genuinely reasonable default for production; `ReleaseFast`
trades them for speed.

Where a check is removed, the situation it was catching becomes **illegal
behaviour**: the same category as C's undefined behaviour, with the same
consequences. The checks are not the definition of correctness, they are a
diagnostic for violating it.

You can override the setting for a scope with `@setRuntimeSafety(true)`, which
is useful for keeping bounds checks in one hot-but-hairy function of an
otherwise `ReleaseFast` build.

<aside>

The snippets on this site build as `ReleaseSmall`, so safety checks are off.
That is why this example is marked as not runnable rather than simply showing
you the panic.

</aside>
