C: Simple Defer, Ready to Use

Role and Value of defer in C

  • Many see a standardized defer as long overdue for C, arguing it would prevent resource leaks and common cleanup bugs, especially for programmers used to C++ RAII.
  • Others say C does not “need” this; existing patterns (gotos, arrow pattern, explicit cleanup blocks) are sufficient and more explicit.
  • Some argue a mature language must grow to address real-world pain points; others fear feature bloat and want C to remain minimal and low-level.

Existing Mechanisms and Implementations

  • GCC’s __attribute__((cleanup)) already provides scope-exit cleanup; Apple’s libc and the Linux kernel use similar patterns.
  • The showcased macro implementation uses GCC nested functions; discussion clarifies:
    • Trampolines (and executable stacks) appear only when nested functions escape via pointers.
    • In the presented usage, no executable stack is needed and calls are optimizable.
  • Clang lacks GCC-style nested functions; alternate approaches include Blocks, cleanup attributes, or custom macros.
  • In C++, scope guards (e.g., Folly, Boost.Scope, homegrown ScopeGuard/lambda patterns) already provide defer-like behavior.

Goto, Structured Programming, and Readability

  • Several commenters defend goto for structured error handling and breaking out of nested loops, citing the Linux kernel as a positive example.
  • Others remain wary, viewing goto as a marker of messy code; alternatives like do { … } while (0) or one-iteration loops with break are used instead.
  • There’s an extended debate on Dijkstra’s critique:
    • One side claims modern goto is heavily “tamed” compared to what he attacked.
    • Another counters that C/C++ goto still breaks structured reasoning and can create irreducible control flow.

Visibility vs. Hidden Control Flow

  • Pro-defer camp: less boilerplate, fewer missed cleanups, clearer intent (“do X, and when leaving, do Y”).
  • Skeptics: defer (and C++ destructors) introduce invisible jumps and non-obvious execution order, especially with nested defers; they prefer explicit error paths with clearly ordered teardown.
  • Some suggest tooling that “desugars” defer to explicit gotos as a compromise between high-level clarity and low-level inspectability.

Exceptions and Unwinding Interactions

  • C standard does not define interaction with C++ exceptions; behavior is compiler- and flag-dependent.
  • GCC’s cleanup can participate in stack unwinding when -fexceptions is enabled, but this is non-default and not universal.
  • Consensus: interaction with exceptions is important in mixed C/C++ code but currently unclear for a standardized defer.