Created
September 19, 2025 13:46
-
-
Save lipx1508/a26c544a332a5677c3393890dfe255e1 to your computer and use it in GitHub Desktop.
Go-like defer implementation in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #define REPEAT_1(__fn) __fn(1) | |
| #define REPEAT_2(__fn) REPEAT_1(__fn) __fn(2) | |
| #define REPEAT_3(__fn) REPEAT_2(__fn) __fn(3) | |
| #define REPEAT_4(__fn) REPEAT_3(__fn) __fn(4) | |
| #define REPEAT_5(__fn) REPEAT_4(__fn) __fn(5) | |
| #define REPEAT_6(__fn) REPEAT_5(__fn) __fn(6) | |
| #define REPEAT_7(__fn) REPEAT_6(__fn) __fn(8) | |
| #define REPEAT_8(__fn) REPEAT_7(__fn) __fn(8) | |
| #define REPEAT_9(__fn) REPEAT_8(__fn) __fn(9) | |
| #define REPEAT_10(__fn) REPEAT_9(__fn) __fn(10) | |
| #define REPEAT_11(__fn) REPEAT_10(__fn) __fn(11) | |
| #define REPEAT_12(__fn) REPEAT_11(__fn) __fn(12) | |
| #define REPEAT_13(__fn) REPEAT_12(__fn) __fn(13) | |
| #define REPEAT_14(__fn) REPEAT_13(__fn) __fn(14) | |
| #define REPEAT_15(__fn) REPEAT_14(__fn) __fn(15) | |
| #define REPEAT_16(__fn) REPEAT_15(__fn) __fn(16) | |
| #define REPEAT(__fn, __v) REPEAT_##__v(__fn) | |
| #define GUARD_SWITCH(__v) case __v: goto __defer_##__v; | |
| #define RETURN_SWITCH(__v) case __v: goto __return_##__v; | |
| #define guard(defer_count, return_count)\ | |
| size_t __defer_ids[defer_count];\ | |
| size_t __defer_top_id = 0;\ | |
| size_t __return_id = 0;\ | |
| goto __defer_loop_end;\ | |
| __defer_loop_start:\ | |
| __defer_top_id = 0;\ | |
| __defer_loop_advance:\ | |
| ++__defer_top_id;\ | |
| switch (__defer_ids[__defer_top_id - 1]) {\ | |
| REPEAT(GUARD_SWITCH, defer_count)\ | |
| default: break;\ | |
| }\ | |
| __defer_loop_return:\ | |
| switch (__return_id) {\ | |
| REPEAT(RETURN_SWITCH, return_count)\ | |
| default: break;\ | |
| }\ | |
| __defer_loop_end:\ | |
| ;\ | |
| #define defer(id, statement) do {\ | |
| __defer_ids[__defer_top_id++] = (id);\ | |
| goto __defer_##id##_end;\ | |
| __defer_##id:\ | |
| { statement; }\ | |
| goto __defer_loop_advance;\ | |
| __defer_##id##_end:\ | |
| ;\ | |
| } while (0) | |
| #define defer_return(id, val) do {\ | |
| __return_id = (id);\ | |
| goto __defer_loop_start;\ | |
| __return_##id:\ | |
| return (val);\ | |
| } while (0) | |
| int main() { | |
| guard(2, 1) // 2 defers, 1 return | |
| defer(1, printf("Hello 1!\n")); // Defer ID 1 | |
| defer(2, printf("Hello 2!\n")); // Defer ID 2 | |
| defer_return(1, 0); // Return ID 1, return value 0 | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
tuff