Why not just do simple C++ RAII in C?
Programmers debate whether C should gain C++-style RAII destructors or a simpler `defer` mechanism for automatic cleanup, highlighting how C’s lack of an object model and complicated “effective type” rules make true RAII hard to graft on. Many argue that importing C++-like semantics would explode C’s complexity and break its “what you see is what you get” ethos, while others counter that C++’s rule-of-0/3/5 and Rust’s ownership model show RAII can be made safer with the right design. The prevailing view favors minimal features like `defer` or arenas, keeping C small and explicit, and leaving full RAII and richer abstractions to languages such as C++, Rust, Zig, or D.
RAII in C vs C++
- Many argue that full C++-style RAII depends on C++’s complex object model (constructors, destructors, copy/move semantics, special member rules).
- Some say these rules (0/3/5) are simple in practice if followed mechanically; others call them arcane, emergent complexity that surprises newcomers and breaks code in non-obvious ways.
- Several note that C++ “struct” is not a plain C struct; once you add non-trivial behavior, C++’s lifetime and object rules apply, unlike C’s simple “bag of bits” model.
Why “Just Add RAII to C” Is Contentious
- One view: you can’t bolt on destructors without importing a lot of C++-like machinery (object lifetime rules, copying/moving, possibly name mangling or overloading).
- Another view: you could add some notion of constructors/destructors and copy/move behavior in a C-specific way; past proposals are called incomplete rather than fundamentally impossible.
- A recurring technical sticking point: what happens when a struct with cleanup semantics is copied, moved, or embedded inside other structs, and who “owns” the resource.
Defer, Cleanup Contexts, and Alternatives
- Many favor a
defer-style construct for C, or compiler-supported cleanup attributes, as a simpler, scope-based way to ensure teardown without full RAII. - Others propose thread-local “cleanup contexts” or callback lists instead of object-based lifetimes.
- Some point out this is more like structured cleanup than full RAII: it doesn’t handle non-lexical lifetimes or complex ownership graphs.
Memory Management Models (RAII vs GC vs Others)
- Several contrast C’s “you’re on your own” model with RAII (C++, Rust), GC (Go/Java), and ARC (Objective‑C/Swift).
- Rust is repeatedly cited as having a cleaner ownership/move model: no implicit copying for types with destructors, explicit
clone, and moves that don’t leave “zombie” objects. - Zig is discussed as an example of explicit allocators, arenas, and
defer, plus safety‑checked undefined behavior; some emphasize these patterns could be done in C but aren’t culturally.
“Don’t Ruin C” vs “C Is Already Too Sharp”
- One camp wants C to stay minimal and predictable, fearing feature creep will turn it into “C++‑lite.”
- Another counters that real-world C already has pervasive undefined behavior and macro tricks; it is not actually simple or safe, just low-level.