# Integer Overflow

### Integer Overflow

An integer type can store only a fixed range of values.

For example:

| Type | Range |
|---|---|
| `u8` | `0` to `255` |
| `i8` | `-128` to `127` |
| `u16` | `0` to `65535` |

When a calculation produces a value outside the range of the type, overflow occurs.

In Zig, ordinary arithmetic checks for overflow in safe build modes.

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

pub fn main() void {
    var x: u8 = 255;

    x += 1;

    std.debug.print("{d}\n", .{x});
}
```

The value `256` does not fit in `u8`.

In Debug mode, Zig stops the program:

```text
panic: integer overflow
```

This behavior is deliberate.

Silent overflow is a common source of bugs in systems programs. Zig requires the programmer to choose overflow behavior explicitly.

If wrapping arithmetic is wanted, use wrapping operators.

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

pub fn main() void {
    var x: u8 = 255;

    x +%= 1;

    std.debug.print("{d}\n", .{x});
}
```

The result is:

```text
0
```

The value wraps around modulo `256`.

Wrapping operators exist for the main arithmetic operations.

| Operator | Meaning |
|---|---|
| `+%` | Wrapping addition |
| `-%` | Wrapping subtraction |
| `*%` | Wrapping multiplication |

Assignment forms also exist:

| Operator | Meaning |
|---|---|
| `+%=` | Wrapping addition assignment |
| `-%=` | Wrapping subtraction assignment |
| `*%=` | Wrapping multiplication assignment |

Signed integers can also overflow.

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

pub fn main() void {
    var x: i8 = 127;

    x += 1;

    std.debug.print("{d}\n", .{x});
}
```

`127` is the largest `i8`.

Adding `1` overflows.

Wrapping signed integers uses two's complement behavior.

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

pub fn main() void {
    var x: i8 = 127;

    x +%= 1;

    std.debug.print("{d}\n", .{x});
}
```

The result is:

```text
-128
```

Sometimes overflow should be detected directly instead of trapping or wrapping.

Zig provides operations that return both the result and an overflow flag.

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

pub fn main() void {
    const result = @addWithOverflow(250, 10);

    const value = result[0];
    const overflow = result[1];

    std.debug.print("{d} {d}\n", .{
        value,
        overflow,
    });
}
```

The result is:

```text
4 1
```

The addition wrapped, and the overflow flag is set.

The builtins are:

| Builtin | Meaning |
|---|---|
| `@addWithOverflow` | Addition with overflow flag |
| `@subWithOverflow` | Subtraction with overflow flag |
| `@mulWithOverflow` | Multiplication with overflow flag |
| `@shlWithOverflow` | Shift-left with overflow flag |

These are useful in parsers, cryptography, allocators, and arithmetic libraries.

Integer overflow matters because the compiler uses arithmetic assumptions during optimization.

Consider:

```zig
if (x + 1 > x) {
    // ...
}
```

For ordinary checked arithmetic, the compiler may assume the expression behaves mathematically when overflow is impossible.

When wrapping behavior is required, use explicit wrapping operators so the meaning is clear.

Shift operations are also checked.

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

pub fn main() void {
    const x: u8 = 1;

    const y = x << 8;

    std.debug.print("{d}\n", .{y});
}
```

A `u8` has only eight bits. Shifting by eight exceeds the bit width.

In safe modes, this is a panic.

Exact-width integer types make overflow rules predictable.

```zig
const a: u32 = 1000;
const b: i16 = -5;
```

The size and signedness are always explicit.

Zig avoids implicit integer widening and narrowing in many situations.

```zig
const a: u8 = 10;
const b: u16 = 20;

// error
const c = a + b;
```

The compiler requires an explicit conversion.

```zig
const c = @as(u16, a) + b;
```

This prevents accidental loss of range or sign.

Integer overflow is sometimes useful.

Hash functions often rely on wrapping arithmetic.

```zig
hash = hash *% 33 +% byte;
```

Counters and indexes usually should not overflow.

```zig
count += 1;
```

The ordinary operator expresses the safer intent.

The general rule is simple:

| Situation | Preferred operation |
|---|---|
| Overflow is a bug | `+`, `-`, `*` |
| Overflow is intended | `+%`, `-%`, `*%` |
| Overflow must be detected | `@addWithOverflow` |

The language forces the choice into the source code instead of hiding it in compiler rules.

Exercise 19-13. Write a program that overflows a `u8` with `+=`.

Exercise 19-14. Rewrite Exercise 19-13 with `+%=`.

Exercise 19-15. Use `@addWithOverflow` to add two `u16` values and print both the result and overflow flag.

Exercise 19-16. Write a simple hash loop that uses wrapping multiplication.

