This doesn’t require GCC extensions (although it can take advantage of them for a speedboost). It also lets you defer straight expressions; the GCC extension makes you call a function, which means you have to make a nested function that possibly doesn’t close over local variables. Big mess.
The cleanup attribute runs a function when the variable goes out of scope. This attribute can only be applied to auto function scope variables; it may not be applied to parameters or variables with static storage duration. The function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
If -fexceptions is enabled, then cleanup_function is run during the stack unwinding that happens during the processing of the exception. Note that the cleanup attribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.
I would implement this with C++, where it’s a trivial RAII class with some macros as syntactic sugar.
Then it’s just a matter of compiling your C code as C++ with a compiler flag. You can still write in C, you just have access to more features if you want them.
Just a little while ago I took a take on it with C++. The post is in German, but the code should be understandable (the second code block is the implementation, the third code block shows the usage). Try your favourite translator for the explanation of how it works :-)
Weird, I remember reading that GCC has deferrals as an extension, I don’t remember where, but it was as simple as putting an attribute on something
This doesn’t require GCC extensions (although it can take advantage of them for a speedboost). It also lets you defer straight expressions; the GCC extension makes you call a function, which means you have to make a nested function that possibly doesn’t close over local variables. Big mess.
Correct:
systemd uses macros to do similar things.
What’s the problem with the setjmp/longjmp-based variant of the implementation, that it needs a warning?
It employs undefined behaviour, and tends to have problems. Working on it…
Looking at the source, does this need GNU C extensions? Because it looks like the header is wrapped in a
#ifdef __GNUC__
…No. There is a version which uses gnu computed goto, but also a version which uses standard setjmp/longjmp.
This is way cool! I’m blown away that this is possible in C. Well done.
I would implement this with C++, where it’s a trivial RAII class with some macros as syntactic sugar.
Then it’s just a matter of compiling your C code as C++ with a compiler flag. You can still write in C, you just have access to more features if you want them.
Some projects may not want C++ as a dependency.
I wrote about this on reddit.
The problem with C++ is that my colleagues have access to features I don’t want. 😉
But then your compile times will be inflated by a factor of 10.
Which is still a factor of ten faster than trendy languages like Rust and Swift, amirite?
Just a little while ago I took a take on it with C++. The post is in German, but the code should be understandable (the second code block is the implementation, the third code block shows the usage). Try your favourite translator for the explanation of how it works :-)
I recommend using
__COUNTER__
over__LINE__
, where supported, because that way you can have multiple deferred things on the same line.