|
ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
|
🔄 Go/Zig-style defer statements for automatic cleanup in C More...
Files | |
| file | defer.h |
| Defer macro definition for source-to-source transformation. | |
Macros | |
| #define | defer(action) |
| Defer a cleanup action until function scope exit. | |
🔄 Go/Zig-style defer statements for automatic cleanup in C
This header provides the defer() macro syntax that is recognized by the ascii-instr-defer tool. The tool transforms defer() calls into inlined cleanup code at all function exit points.
Example usage: FILE *f = fopen("file.txt", "r"); defer(fclose(f)); // Will be called when function exits
The defer transformer converts this to: FILE *f = fopen("file.txt", "r"); // ... at every return point and function end: { fclose(f); }
Note: This header only defines the macro for parsing. The actual cleanup code is generated by the transformer - no runtime library is needed.
This module implements Go/Zig-style defer statements for C using Clang libTooling source-to-source transformation. Defer allows cleanup code to run automatically at function exit, regardless of the exit path (return, goto, end of function).
Key Design Decision: No runtime library is needed. The transformer directly inlines cleanup code at every exit point, making defer zero-overhead at runtime.
Implementation: src/tooling/defer/tool.cpp
Key Features:
defer()cmake/tooling/Defer.cmakeThe defer tool transforms source code by directly inlining cleanup code at every function exit point. No runtime library is needed.
Original Code:
Transformed Code:
Transformation Rules:
defer(expression); statements{ expression; } before:return statementgoto targets outside the defer scopedefer() call is removedThe header provides a no-op macro so IDEs and editors can parse code that uses defer():
This allows:
Defer transformation is enabled automatically when files contain defer() calls.
How it works:
defer( usagedefer() are transformedbuild/defer_transformed/Key features:
.deps-cache/defer-tool/The defer tool supports any single expression:
defer(fclose(file));defer(printf("cleanup\n"));defer(cleanup_resource(res, flags));defer((void)(count++, cleanup()));Defer applies to function scope, not block scope:
Since cleanup code is inlined:
Defer Advantages:
Manual Disadvantages:
Defer Advantages:
Attribute Disadvantages:
src/tooling/defer/tool.cppsrc/tooling/defer/CMakeLists.txtcmake/tooling/Defer.cmakelib/tooling/defer/defer.h.deps-cache/defer-tool/ascii-instr-deferbuild/defer_transformed/Defer not working:
defer( (CMake only transforms files with defer usage)cmake --build buildcat build/defer_transformed/path/to/file.cTool not building:
ls .deps-cache/defer-tool/ascii-instr-defer*rm -rf .deps-cache/defer-tool && cmake --build buildIDE shows errors:
lib/tooling/defer/defer.h to provide the macro stubdefer() a valid no-op for parsing| #define defer | ( | action | ) |
#include <defer.h>
Defer a cleanup action until function scope exit.
| action | The cleanup expression to execute (e.g., fclose(f), free(ptr)) |
The defer() macro marks cleanup code that should run when the function exits. The ascii-instr-defer tool transforms these into inlined cleanup code.
Multiple defers execute in LIFO (last-in-first-out) order.
Definition at line 36 of file defer.h.