Earlier quoted context omitted.
Perhaps I'm misunderstanding this, but this doesn't solve the problem at all -- returning within the block statement wouldn't call the deferred expression, which is entirely the point of a defer statement, no? If control is guaranteed to reach the end of the block statement, of course; but requiring such a constraint would make this defer very handicapped. You have tons of function exit points and you most likely wan…
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.
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.