# RAII

RAII — Resource Acquisition Is Initialization — is the discipline of tying a resource's lifetime to an object's lifetime. The constructor acquires the resource (memory, file descriptor, lock, socket); the destructor releases it. As long as the object is destroyed deterministically, the resource is released deterministically. No `try`/`finally`. No paired-call discipline at every call site.

The name is misleading enough that even Stroustrup later called it a poor choice — what matters is the destructor running, not the constructor doing acquisition. "Scoped resource management" describes it more honestly. But the acronym stuck.

## The shape

A type wraps a resource. Its constructor acquires; its destructor releases; copy and move semantics make ownership explicit at the type level. Anyone holding the object holds the resource; when the object dies, the resource is freed. C++ destructors fire on scope exit, on exception unwinding, on container element removal, and on smart-pointer reset — uniformly, without programmer attention.

The standard library's `unique_ptr`, `shared_ptr`, `lock_guard`, `fstream`, `vector`, and `string` are all RAII types. So is every Rust type with a `Drop` impl — Rust took RAII as a baseline and made it the only memory-management story.

## Why it works

The argument [[stroustrup-memory-leaks]] makes is operational, not aesthetic: a human can track a few dozen objects, not tens of thousands of allocations. RAII collapses the bookkeeping. Once a resource has an owner, the question of *who frees it* becomes the question of *who owns it*, and ownership is visible at the type signature. Pointer-arithmetic code answers neither question; RAII code answers both by construction.

This generalizes beyond memory. File handles, mutex locks, database transactions, GPU resources, and reference counts all share the acquire/release pattern. RAII is the encoding of that pattern in the type system.

## What it requires from the language

RAII needs deterministic destruction — destructors that fire at known points (scope exit, container removal, smart-pointer reset), not "eventually, when GC notices." Languages with non-deterministic finalizers (Java, Python, Go) cannot do RAII directly; they fall back to `try`-with-resources, `with` blocks, or `defer`, all of which require the programmer to remember to opt in.

Garbage-collected languages can manage memory without RAII because memory is fungible — slightly delayed reclamation is fine. They cannot manage *non-fungible* resources (file handles, locks, network sockets) the same way, which is why Java grew `try`-with-resources and Python grew context managers. RAII is the C++/Rust answer to the same problem, applied uniformly.

## Connections

- [[stroustrup-memory-leaks]] — the canonical short statement of RAII as memory-leak prevention
- [[simplified-model-of-fil-c]] — Fil-C bolts memory safety onto C/C++ via GC because the discipline of RAII isn't enforceable in legacy code
- [[pointer-provenance]] — pointers carry allocation identity; RAII puts that identity inside an owning type
- [[no-silver-bullet]] — RAII is one of the rare attacks on accidental complexity that produced an order-of-magnitude reduction in a specific bug class
