This all started because I was complaining about some uninitialized pointer value causing me grief1 and someone (explicitly trolling) said they always check pointers using:

int fds[2] = { -1, -1}; 
pipe(fds);
if (write(fds[0], pointer_to_check, sizeof(intptr_t)) == -1) {
    close(fds[0]);
    close(fds[1]);
    return not_valid;
} else {
    close(fds[0]);
    close(fds[1]);
    return valid;
}

In case it’s not abundantly clear, you should never do this2, but of course the first thing I saw was the duplication of code responsible for managing resources, a reminder of how redundant and error-prone C can be.

A different formulation of this code might look like:

int rc, fds[2] = { -1, -1}; 
pipe(fds);
if (write(fds[0], pointer_to_check, sizeof(intptr_t)) == -1) {
    rc = not_valid;
} else {
    rc = valid;
}
close(fds[0]);
close(fds[1]);
return rc;

This reduces duplication, but has worse locality. I don’t love it, but I feel like it’s the safer style.

Really what I want is something like Swift’s defer:

int fds[2] = { -1, -1}; 
pipe(fds);
defer ^{
    close(fds[0]);
    close(fds[1]);
};

if (write(fds[0], pointer_to_check, sizeof(intptr_t)) == -1) {
    return not_valid;
} else {
    return valid;
}

Turned out it’s not too heinous to hack together, it produces efficient assembly, and it’s even exception-safe!

Here it is:

__attribute__((unused))
static void __defer_cleanup(void (^*pBlock)(void)){ (*pBlock)(); }
#define __defer_tokenpaste(prefix, suffix) prefix ## suffix
#define __defer_blockname(nonce) __defer_tokenpaste(__defer_, nonce)

/* Declare a local block variable with a unique name that contains
 * the cleanup code. It has three attributes:
 *   unused: because you should NEVER touch this local yourself
 *   deprecated: because you should NEVER touch this local yourself
 *   cleanup: to get its pointer passed to __defer_cleanup (above)
 *                when the scope ends
 */
#define defer \
void (^ __defer_blockname(__LINE__))(void) \
__attribute__((unused, \
               deprecated("hands off!"), \
               cleanup(__defer_cleanup) \
)) =