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.