diff --git a/handle.h b/handle.h new file mode 100644 index 0000000..a4b926e --- /dev/null +++ b/handle.h @@ -0,0 +1,57 @@ +#ifndef MAG_HANDLE_H +#define MAG_HANDLE_H + +#ifdef __cplusplus +#error "handle.h does not work with C++ compilers, you must compile these files with GCC directly!" +#endif + +/** Tells your constructor/destructor handler function about the state */ +enum HANDLE_STATE { + HANDLE_CREAT, + HANDLE_DESTR, +}; + +/** + * This creates a "handle". Basically a struct with given constructor and destructor + RAII. + * + * Usage: + * + * struct Meaning { + * int a; + * int b; + * }; + * // You can typedef if you want, change code accordingly! + * + * handle(struct Meaning) { + * if(state == HANDLE_CREAT) { + * this->a = *(int*) data; + * this->b = 2 + * } else { + * printf("%d\n", this->a + this->b); + * } + * } + * + * // Now you can use a handle in your local scopes + * // Should print 42: + * int main() { + * int initializer = 40; + * creat(struct Data, d, &initializer); + * } + * + * Rem.: Unrelated trick, but you can typedef struct A A; // both typedef and forward declare + */ + +#define creat(TNAME, VNAME, VINIT) \ + [[gnu::always_inline]] inline void F(TNAME *v) { \ + TNAME##_lifetime_handler(HANDLE_DESTR, v, NULL); \ + } \ + [[gnu::cleanup(F)]] TNAME VNAME; \ + TNAME##_lifetime_handler(HANDLE_CREAT, VNAME, VINIT); + +#define handle(TNAME) \ + static void [[gnu::always_inline]] inline TNAME##_lifetime_handler( \ + HANDLE_STATE state, \ + TNAME *this, \ + void *data) + +#endif // MAG_HANDLE_H diff --git a/handle_test.c b/handle_test.c new file mode 100644 index 0000000..f4eea67 --- /dev/null +++ b/handle_test.c @@ -0,0 +1,4 @@ +#include + +int main() { +} diff --git a/innerf.c b/innerf.c index 5bfcaec..4938601 100644 --- a/innerf.c +++ b/innerf.c @@ -5,12 +5,13 @@ int main() { int b = 40; int c = 2; + // See: https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Nested-Functions.html inline void lf(register int* r) { a += *r; }; // semicolon(;) not needeed! /* - // Same as above... + // Same as above... but need auto storage class if you pre-declare inline auto void lf(register int* r); inline void lf(register int* r) { a += *r; diff --git a/makefile b/makefile index 2aa9b67..7cb0964 100644 --- a/makefile +++ b/makefile @@ -7,6 +7,7 @@ gcc: gcc construct_destruct.c -o construct_destruct gcc raii_test.c -o raii_test g++ raii_test.cpp -o raii_test_cpp + gcc handle_test.c -o handle_test clang: clang macroname.c -o macroname clang count.c -o count