# Can errdefer and defer be combined?

**URL:** <https://ziggit.dev/t/can-errdefer-and-defer-be-combined/9670>\
**Category:** Explain\
**Created:** [April 16, 2025, 9:34pm UTC](https://ziggit.dev/t/can-errdefer-and-defer-be-combined/9670 "2025-04-16T21:34:50Z")\
**Posts on this page:** 3\
**Page:** 3

<div class="post-metadata">

**Author:** ![Tosti](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/b38774/32.png) [@Tosti](https://ziggit.dev/u/Tosti)\
**Post date:** [May 4, 2025, 12:23pm UTC](https://ziggit.dev/t/can-errdefer-and-defer-be-combined/9670/41 "2025-05-04T12:23:18Z")

</div>

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

```zig
// 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](https://dlang.org/spec/statement.html#scope-guard-statement)) (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)`.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [May 7, 2025, 9:34pm UTC](https://ziggit.dev/t/can-errdefer-and-defer-be-combined/9670/42 "2025-05-07T21:34:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![mnemnion](https://ziggit.dev/user_avatar/ziggit.dev/mnemnion/32/2478_2.png) [@mnemnion](https://ziggit.dev/u/mnemnion)\
**Post date:** [May 16, 2025, 4:53pm UTC](https://ziggit.dev/t/can-errdefer-and-defer-be-combined/9670/43 "2025-05-16T16:53:27Z")

</div>

> [@Tosti](#):
>
> 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.

How about this?

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

```

Seems clear enough.

[Previous page](https://ziggit.dev/t/can-errdefer-and-defer-be-combined/9670.md?page=2)
