-
-
Save baruch/f005ce51e9c5bd5c1897ab24ea1ecf3b to your computer and use it in GitHub Desktop.
| #define DEFER_MERGE(a,b) a##b | |
| #define DEFER_VARNAME(a) DEFER_MERGE(defer_scopevar_, a) | |
| #define DEFER_FUNCNAME(a) DEFER_MERGE(defer_scopefunc_, a) | |
| #define DEFER(BLOCK) void DEFER_FUNCNAME(__LINE__)(int *a) BLOCK; __attribute__((cleanup(DEFER_FUNCNAME(__LINE__)))) int DEFER_VARNAME(__LINE__) | |
| // Usage: | |
| /* | |
| void dosomething() | |
| { | |
| char* data = malloc(100); | |
| DEFER({ free(data); }); | |
| dosomethingwith(data); | |
| } | |
| */ |
clang 10.0.0
char (* buff_ptr_)[buffer_size()] = {0} ;
DEFER({free(buff_ptr_) ;});I get: "Function definition is not allowed here"? Perhaps nested functions need some switch for clang?
I'm not sure, I have a different piece of code utilizing this in my libwire wire_defer.h but that code is marked GCC only. I don't remember why is that anymore.
compiles using clang ... but "disappears" upon execution?
Try this https://godbolt.org/z/6Y8Ys4dPo
Any C version and any compiler.
Nice! You can add __attribute__((unused)) before the int *a parameter to get rid of the unused-parameter warning:
...
#define DEFER(BLOCK) void DEFER_FUNCNAME(__LINE__)(__attribute__((unused)) int *a) BLOCK; __attribute__((cleanup(DEFER_FUNCNAME(__LINE__)))) int DEFER_VARNAME(__LINE__)
Now simpler to re-use: https://godbolt.org/z/zsYre5Kfj
@sinecode
Did you manage to get rid of the warning: ISO C forbids nested functions [-Wpedantic] warning?
Try this https://godbolt.org/z/6Y8Ys4dPo
Any C version and any compiler.
Now simpler to re-use: https://godbolt.org/z/zsYre5Kfj
Problem with the for loop approach:
defer( close_file( dummsy_ )) {
// Do something with the file
if (/* something failed */)
return;
// ...and now close_file doesn't get called 🧨
}
Inspired by http://fdiv.net/2015/10/08/emulating-defer-c-clang-or-gccblocks
But this version doesn't use the special extension "blocks" that doesn't exist in a normal gcc.