# C goto vs Zig defer / errdefer / break

**URL:** <https://ziggit.dev/t/c-goto-vs-zig-defer-errdefer-break/2952>\
**Category:** Brainstorming\
**Tags:** language, c\
**Created:** [January 20, 2024, 11:00am UTC](https://ziggit.dev/t/c-goto-vs-zig-defer-errdefer-break/2952 "2024-01-20T11:00:14Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![dee0xeed](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/3ab097/32.png) [@dee0xeed](https://ziggit.dev/u/dee0xeed)\
**Post date:** [January 20, 2024, 5:50pm UTC](https://ziggit.dev/t/c-goto-vs-zig-defer-errdefer-break/2952/4 "2024-01-20T17:50:23Z")

</div>

> [@pierrelgol](#):
>
> …than to keep track of 10 different label.

ten?!? 🙂 you’re kidding..  
One label is more than enough:

```c
bool do_smth(... result *r) {

    int fd1 = -1;
    int fd2 = -1;
    void *m1 = NULL;
    void *m2 = NULL;

    fd1 = open(...);
    if (-1 == fd1) {
        ...
        goto __failure;
    }

    fd2 = open(...);
    if (-1 == fd2) {
        ...
        goto __failure;
    }

    m1 = malloc(...);
    if (NULL == m1) {
        ...
        goto __failure;
    }

    m2 = malloc(...);
    if (NULL == m2) {
        ...
        goto __failure;
    }

    r->fd1 = fd1;
    r->fd2 = fd2;
    r->m1 = m1;
    r->m2 = m2;
    return true;

  __failure:
    if (-1 != fd1)
        close(fd1);
    if (-1 != fd2)
        close(fd2);
    if (NULL != m1)
        free(m1);
    if (NULL != m2)
        free(m2);
    return false;
}

```

I’ve never seen more clear cleanup pattern than this one.

---

_[View the full topic](https://ziggit.dev/t/c-goto-vs-zig-defer-errdefer-break/2952)._
