C: Simple Defer, Ready to Use
Role and Value of defer in C
- Many see a standardized
deferas 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,
cleanupattributes, 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
gotofor structured error handling and breaking out of nested loops, citing the Linux kernel as a positive example. - Others remain wary, viewing
gotoas a marker of messy code; alternatives likedo { … } while (0)or one-iteration loops withbreakare used instead. - There’s an extended debate on Dijkstra’s critique:
- One side claims modern
gotois heavily “tamed” compared to what he attacked. - Another counters that C/C++
gotostill breaks structured reasoning and can create irreducible control flow.
- One side claims modern
Visibility vs. Hidden Control Flow
- Pro-
defercamp: 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”
deferto 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
cleanupcan participate in stack unwinding when-fexceptionsis 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.