Skip to content

Instantly share code, notes, and snippets.

@baruch
Created May 27, 2018 19:09
Show Gist options
  • Save baruch/f005ce51e9c5bd5c1897ab24ea1ecf3b to your computer and use it in GitHub Desktop.
Save baruch/f005ce51e9c5bd5c1897ab24ea1ecf3b to your computer and use it in GitHub Desktop.
Defer cleanup for C (gcc and llvm)
#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);
}
*/
@baruch
Copy link
Author

baruch commented May 27, 2018

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.

@DBJDBJ
Copy link

DBJDBJ commented Dec 24, 2020

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?

@BaruchWeka
Copy link

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.

@DBJDBJ
Copy link

DBJDBJ commented Dec 26, 2020

https://godbolt.org/z/YaKEGY

compiles using clang ... but "disappears" upon execution?

@DBJDBJ
Copy link

DBJDBJ commented Apr 11, 2021

Try this https://godbolt.org/z/6Y8Ys4dPo

Any C version and any compiler.

@sinecode
Copy link

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__)

@DBJDBJ
Copy link

DBJDBJ commented Jul 16, 2021

Now simpler to re-use: https://godbolt.org/z/zsYre5Kfj

@g-berthiaume
Copy link

@sinecode
Did you manage to get rid of the warning: ISO C forbids nested functions [-Wpedantic] warning?

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