Defer available in gcc and clang

gustedt.wordpress.com

215 points by r4um 4 days ago


kjgkjhfkjf - 8 hours ago

The article is a bit dense, but what it's announcing is effectively golang's `defer` (with extra braces) or a limited form of C++'s RAII (with much less boilerplate).

Both RAII and `defer` have proven to be highly useful in real-world code. This seems like a good addition to the C language that I hope makes it into the standard.

LexiMax - 8 hours ago

A long overdue feature.

Though I do wonder what the chances are that the C subset of C++ will ever add this feature. I use my own homespun "scope exit" which runs a lambda in a destructor quite a bit, but every time I use it I wish I could just "defer" instead.

jonhohle - 8 hours ago

It’s pedantic, but in the malloc example, I’d put the defer immediately after the assignment. This makes it very obvious that the defer/free goes along with the allocation.

It would run regardless of if malloc succeeded or failed, but calling free on a NULL pointer is safe (defined to no-op in the C-spec).

t43562 - 4 hours ago

In C I just used goto - you put a cleanup section at the bottom of your code and your error handling just jumps to it.

  #define RETURN(x) result=x;goto CLEANUP

  void myfunc() {
    int result=0;
    if (commserror()) {
      RETURN(0);
    }
     .....
    /* On success */
    RETURN(1);

    CLEANUP:
    if (myStruct) { free(myStruct); }
    ...
    return result
  }
The advantage being that you never have to remember which things are to be freed at which particular error state. The style also avoids lots of nesting because it returns early. It's not as nice as having defer but it does help in larger functions.
cmovq - 6 hours ago

Would defer be considered hidden control flow? I guess it’s not so hidden since it’s within the same function unlike destructors, exceptions, longjmp.

babalark - 8 hours ago

Yes!! One step closer to having defer in the standard.

Related blog post from last year: https://thephd.dev/c2y-the-defer-technical-specification-its... (https://news.ycombinator.com/item?id=43379265)

ozgrakkurt - 5 hours ago

Can somebody explain why this is significantly better than using goto pattern?

Genuinely curious as I only have a small amount of experience with c and found goto to be ok so far

joexbayer - 6 hours ago

A related article discussing Gustedt’s first defer implementation, which also looks at the generated assembly:

https://oshub.org/projects/retros-32/posts/defer-resource-cl...

bjackman - 4 hours ago

The Linux kernel has been using __attribute___((cleanup)) for a little while now. So far, I've only seen/used it in cases where the alternative (one goto label) isn't very bad. Even there it's basically welcome.

But there are lots of cases in the kernel where we have 10+ goto labels for error paths in complex setup functions. I think when this starts making its way into those areas it will really start having an impact on bugs.

Sure, most of those bugs are low impact (it's rare that an attacker can trigger the broken error paths) but still, this is basically free software quality, it would be silly to leave it on the table.

And then there's the ACTUAL motivation: it makes the code look nicer.

gignico - 7 hours ago

I’m just going to start teaching classes of C programming to university first-year CS students. Would you teach `defer` straight away to manage allocated memory?

userbinator - 8 hours ago

As others have commented already: if you want to use C++, use C++. I suspect the majority of C programmers neither care nor want stuff like this; I still stay with C89 because I know it will be portable anywhere, and complexities like this are completely at odds with the reason to use C in the first place.

sp1rit - 5 hours ago

I quite dislike the defer syntax. IMO the cleanup attribute is the much nicer method of dealing with RAII in C.

Panzerschrek - 8 hours ago

Such addition is great. But there is something even better - destructors in C++. Anyone who writes C should consider using C++ instead, where destructors provide a more convenient way for resources freeing.

unit149 - 4 hours ago

[dead]

nananana9 - 6 hours ago

I took some shit in the comments yesterday for suggesting "you can do it with a few lines of standard C++" to another similar thread, but yet again here we are.

Defer takes 10 lines to implement in C++. [1]

You don't have to wait 50 years for a committee to introduce basic convenience features, and you don't have to use non-portable extensions until they do (and in this case the __attribute__((cleanup)) has no equivalent in MSVC), if you use a remotely extensible language.

[1] https://www.gingerbill.org/article/2015/08/19/defer-in-cpp/