Can errdefer and defer be combined?

I think that combining defer and errdefer is unnecessary. The only thing that’s missing is an analogue of errdefer that’s executed on success, like successdefer. The OP’s code becomes

// Abandon on error
errdefer parent.abandonContainer(&iter);
// But close only if it doesn't error
successdefer parent.closeContainer(&iter);
// Do other things with iter

I vaguely remember reading a discussion that such a use case is so rare that it doesn’t make sense to add successderef to the language (can’t remember where I’ve seen it). I think that it’s a weak argument, and that successdefer may simplify the code when such a case arises. Unless it adds considerable complexity to the compiler implementation.

errdefer and successdefer are dual to each other and it feels weird to have one but not the other. If you are interested, the D language has analogues of defer/errdefer/successdefer (language reference) (they work with exceptions, but the idea is the same).

@milogreg suggested a nice workaround, but it requires creating an additional variable and an if check. Also, it’s easy to make a mistake if you forget that errdefer returned_err = true; has to come after all defer if (!returned_err).

1 Like

What’s being cleaned up is scoped to the function, so you can’t perform the action outside it.

How about this?

errdefer {
    parent.abandonContainer(&iter);
} else {
    parent.closeContainer(&iter);
}

Seems clear enough.

2 Likes