# Defer

> Cleanup that runs on every path out of a scope.

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

test "defer runs at scope exit" {
    var x: i16 = 5;
    {
        defer x += 2;
        try expect(x == 5); // not yet
    }
    try expect(x == 7); // now
}

test "defers run in reverse order" {
    // Last registered runs first, so cleanup unwinds in the order things
    // were acquired.
    var order: [3]u8 = undefined;
    var index: usize = 0;
    {
        defer {
            order[index] = 1;
            index += 1;
        }
        defer {
            order[index] = 2;
            index += 1;
        }
        defer {
            order[index] = 3;
            index += 1;
        }
    }
    try expect(order[0] == 3);
    try expect(order[2] == 1);
}

fn mightFail(fail: bool) !u8 {
    var cleaned = false;
    // `errdefer` runs only when the function returns an error.
    errdefer cleaned = true;
    if (fail) return error.Nope;
    return @intFromBool(cleaned);
}

test "errdefer only fires on the error path" {
    try expect(try mightFail(false) == 0);
    try std.testing.expectError(error.Nope, mightFail(true));
}
```

*Runnable: compiled to WebAssembly and executed by CI against Zig master. (`02-language.defer`)*

`defer` schedules an expression to run when the enclosing **scope** exits: not
the function, the scope. Every path counts: falling off the end, an early
`return`, or an error propagating through `try`.

## Reverse order is the point

Deferred statements run last-registered-first. That is what makes them compose:
if you acquire A then B, cleanup happens B then A, which is almost always the
correct unwinding order. Writing the release directly under the acquire keeps
the pair visible in one glance:

```zig
const buf = try allocator.alloc(u8, n);
defer allocator.free(buf);
```

## `errdefer` for the failure path only

`errdefer` runs **only** when the function returns an error. This is how you
write a constructor that cleans up partial work without also undoing itself on
success:

```zig
const thing = try create();
errdefer destroy(thing);   // only if a later step fails
try initialise(thing);
return thing;
```

With plain `defer` that would destroy the object you just successfully
returned.
