⚡ Zig Guide LiveUnofficial
✓ Zig 0.17.0-dev.1454+5faa79730On an older Zig?

Inline Loops

const std = @import("std");
const expect = std.testing.expect;

test "inline for over a tuple" {
    // A tuple's elements have different types, so the loop body must be
    // compiled separately for each. That is what `inline` provides.
    const tuple = .{ @as(u8, 1), @as(f32, 2.5), true };
    var count: usize = 0;
    inline for (tuple) |value| {
        if (@TypeOf(value) == bool) count += 10 else count += 1;
    }
    try expect(count == 12);
}

test "inline for over types" {
    const types = [_]type{ u8, u16, u32 };
    var total: usize = 0;
    inline for (types) |T| {
        total += @sizeOf(T);
    }
    try expect(total == 7);
}

test "the loop variable becomes comptime-known" {
    var sum: usize = 0;
    inline for (0..4) |i| {
        // `i` is comptime here, so it can be used where a comptime value
        // is required, such as an array type's length.
        const arr: [i]u8 = undefined;
        sum += arr.len;
    }
    try expect(sum == 6); // 0 + 1 + 2 + 3
}

inline for unrolls at compile time. That is occasionally about performance, but the real reason it exists is types.

Iterating heterogeneous things

A tuple’s elements have different types. A normal loop body is compiled once, so it cannot handle that. An inline for body is compiled separately per iteration, so @TypeOf(value) can differ each time:

inline for (tuple) |value| {
    if (@TypeOf(value) == bool) { ... }
}

This is how std.debug.print walks its arguments, and how serialisation code walks a struct’s fields.

The loop variable becomes comptime-known

Inside inline for (0..4) |i|, i is a comptime value, so it can be used where the compiler demands one (array lengths, type construction, field names):

const arr: [i]u8 = undefined;   // only valid because i is comptime

Use it deliberately

Unrolling multiplies generated code by the iteration count. For a 3-element tuple that is free; for inline for (0..10000) it is a compile-time and binary-size disaster. Reach for inline when you need comptime-ness, not as a performance reflex.