# `defer`

### `defer`

`defer` runs a statement when control leaves the current block.

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

pub fn main() void {
    defer std.debug.print("second\n", .{});
    std.debug.print("first\n", .{});
}
```

The output is:

```text
first
second
```

The deferred statement is written first, but it runs later.

The block matters. A deferred statement runs at the end of the block where it was declared.

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

pub fn main() void {
    {
        defer std.debug.print("leaving inner block\n", .{});
        std.debug.print("inside inner block\n", .{});
    }

    std.debug.print("after inner block\n", .{});
}
```

The output is:

```text
inside inner block
leaving inner block
after inner block
```

This is useful for cleanup. Acquire a resource, then immediately write how it will be released.

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

pub fn main() !void {
    const file = try std.fs.cwd().openFile("input.txt", .{});
    defer file.close();

    // use file here
}
```

The call to `file.close()` will run when `main` returns, whether the function reaches the end or returns early with an error.

This pattern keeps cleanup near acquisition.

```zig
const resource = try acquire();
defer resource.release();

use(resource);
```

The release code is not hidden at the bottom of the function. It appears next to the code that made it necessary.

Deferred statements run in reverse order.

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

pub fn main() void {
    defer std.debug.print("third\n", .{});
    defer std.debug.print("second\n", .{});
    defer std.debug.print("first\n", .{});
}
```

The output is:

```text
first
second
third
```

This order is deliberate. It matches the usual order of cleanup.

```zig
const a = try acquireA();
defer releaseA(a);

const b = try acquireB();
defer releaseB(b);
```

`b` is released before `a`, because `b` was acquired after `a`.

A `defer` statement can modify variables from the surrounding block.

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

pub fn main() void {
    var n: i32 = 0;

    {
        defer n += 1;
        std.debug.print("{d}\n", .{n});
    }

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

The output is:

```text
0
1
```

The deferred statement runs after the inner print and before the final print.

`defer` also runs when a block exits through `break`, `continue`, or `return`.

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

pub fn main() void {
    var i: usize = 0;

    while (i < 3) : (i += 1) {
        defer std.debug.print("leave iteration\n", .{});

        if (i == 1) continue;

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

A `defer` inside a loop body runs at the end of each iteration, because each iteration leaves the loop body block.

`defer` is not a replacement for ownership. It does not decide who owns memory or files. It only says when a statement runs. The programmer still chooses what must be cleaned up.

A common mistake is to defer inside a loop when the intended cleanup should happen after the whole loop.

```zig
while (condition) {
    const item = try acquire();
    defer item.release();

    use(item);
}
```

Here `item.release()` runs at the end of each iteration. That may be correct. If the resource must live beyond the iteration, the `defer` belongs in an outer block.

Use `defer` for actions that must happen exactly once when leaving a scope: closing files, unlocking mutexes, freeing memory, restoring state, and printing diagnostic exits.

Exercise 3-25. Write a program with two deferred prints and observe the order.

Exercise 3-26. Put a `defer` inside an inner block and observe when it runs.

Exercise 3-27. Put a `defer` inside a loop and observe that it runs once per iteration.

Exercise 3-28. Open a file and use `defer` to close it.

