3 ms·
Yes, the only way I could imagine implementing a "proper" defer in C would be to use (like for most insane C hacks) setjmp/longjmp. I'm fairly sure it's explici
by simias 7y ago
Yes, the only way I could imagine implementing a "proper" defer in C would be to use (like for most insane C hacks) setjmp/longjmp. I'm fairly sure it's explicitly forbidden by the Geneva Conventions though.
Alternatively you might be able to use nested functions to guard against a stray return but that's not standard.
- saagarjha 7y agoHow would you implement defer with setjmp/longjmp? I can’t think of anything off the top of my head.
- simias 7y agoYou'd probably have to #define "return" to call longjmp instead. Although I guess at this point you might be better off just have return call the cleanup code. You'd have to be careful to handle the nesting correctly though, which might be slightly easier with setjmp contexts.
- Someone 7y agoI guess you could do something like (couldn’t get Xcode’s clang to compile this, so it probably is buggy) static unsigned int __deferDepth = 0; #define RETURN return #define return ((__deferDepth == 0) ? RETURN : break do_return) #define DEFER(EXPR) \ __label__ do_return; \ for(int _tmp = 1; _tmp; _tmp = (do { \ __deferDepth += 1; \ EXPR; \ __deferDepth -= 1; \ break; \ do_return: \ RETURN; \ }while(0);)) Nested DEFERs could get hairy, though (do you need a stack of __returnNotBreak values?), and there probably are issues if EXPR contains some nested loops with break or return. Regardless, this isn’t C. Statement expressions (and __label_) are a gcc* extension, and if you’re willing to go there, __attribute__((cleanup)) seems the wiser route.