Skip to content

Instantly share code, notes, and snippets.

@lipx1508
Created September 19, 2025 13:46
Show Gist options
  • Select an option

  • Save lipx1508/a26c544a332a5677c3393890dfe255e1 to your computer and use it in GitHub Desktop.

Select an option

Save lipx1508/a26c544a332a5677c3393890dfe255e1 to your computer and use it in GitHub Desktop.
Go-like defer implementation in C
#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;
}
@SPdoesCode
Copy link

tuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment