Live data from Hacker News

Defer available in gcc and clang

gustedt.wordpress.com

71–80 of 262 posts

Re: Defer available in gcc and clang

#71

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

I feel like C people, out of anyone, should respect the code gen wins of defer. Why would you rely on runtime conditional branches for everything you want cleaned up, when you can statically determine what cleanup functions need to be called?

In any case, the biggest advantage IMO is that resource acquisition and cleanup are next to each other. My brain understands the code better when I see "this is how the resource is acquired, this is how the resource will be freed later" next to each other, than when it sees "this is how this resource is acquired" on its own or "this is how the resource is freed" on its own. When writing, I can write the acquisition and the free at the same time in the same place, making me very unlikely to forget to free something.

Re: Defer available in gcc and clang

#72

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

The advantage is that it automatically adds the cleanup code to all exit paths, so you can not forget it for some. Whether this is really that helpful is unclear to me. When we looked at defer originally for C, Robert Seacord hat a list of examples and how the looked before and after rewriting with defer. At that point I lost interest in this feature, because the new code wasn't generally better in my opinion.

But people know it from other languages, and seem to like it, so I guess it is good to have it also in C.

Re: Defer available in gcc and clang

#73
post #56
post #31

Earlier quoted context omitted.

I'd say a lot of users are going to borrow patterns from Go, where you'd typically check the error first. resource, err := newResource() if err != nil { return err } defer resource.Close() IMO this pattern makes more sense, as calling exit behavior in most cases won't make sense unless you have acquired the resource in the first place. free may accept a NULL pointer, but it also doesn't need to be called with one eit…

This example is exactly why RAII is the solution to this problem and not defer.

I love RAII. C++ and Rust are my favourite languages for a lot of things thanks to RAII.

RAII is not the right solution for C. I wouldn't want C to grow constructors and destructors. So far, C only runs the code you ask it to; turning variable declaration into a hidden magic constructor call would, IMO, fly in the face of why people may choose C in the first place.

Re: Defer available in gcc and clang

#74
post #4

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.

Various macro tricks have existed for a long time but nobody has been able to wrap the return statement yet. The lack of RAII-style automatic cleanups was one of the root causes for the legendary goto fail;[1] bug. [1] https://gotofail.com/

I do not see how defer would have helped in this case.

Re: Defer available in gcc and clang

#75
post #58
post #29

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.

It's one of the most commonly adopted feature among C successor languages (D, Zig, Odin, C3, Hare, Jai); given how opinionated some of them are on these topics, I think it's safe to say it's generally well regarded in PL communities.

What I always hated about defer is that you can simply forget or place it in the wrong position. Destructors or linear types (must-use-once types) are a much better solution.

Re: Defer available in gcc and clang

#76

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.

Defer is a very simple feature where all code is still clearly visible and nothing is called behind your back. I write a lot of C++, and it's a vastly more complex language than "C with defer". Defer is so natural to C that all compilers have relatively broadly non-standard ways of mimicking it (e.g __attribute__((cleanup)).

If you want to write C++, write C++. If you want to write C, but want resource cleanup to be a bit nicer and more standard than __attribute__((cleanup)), use C with defer. The two are not comparable.

Re: Defer available in gcc and clang

#77
post #49
post #36

Earlier quoted context omitted.

IMHO, it is in the best interest of your students to teach them standard C first.

I was under the wrong assumption that defer was approved for the next standard already.

We will likely decide in March that it will became an ISO TS. Given the simplicity of the feature and its popularity, I would assume that it will become part of the standard eventually.

Re: Defer available in gcc and clang

#78

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 equiva…

Why is this a relevant comment? We're talking about C, not C++. If you wanted to suggest using an alternative language, you're probably better off recommending Zig: defer takes 0 lines to implement there, and it's closer to C than what C++ is.

Re: Defer available in gcc and clang

#79
post #61
post #4

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.

Never, you can already do this with RAII, and naturally it would be yet another thing to complain about C++ adding features. Then again, if someone is willing to push it through WG21 no matter what, maybe.

C++ implementations of defer are either really ugly thanks to using lambdas and explicitly named variables which only exist to have scoped object, or they depend on macros which need to have either a long manually namespaced name or you risk stepping on the toes of a library. I had to rename my defer macro from DEFER to MYPOROGRAM_DEFER in a project due to a macro collision.

C++ would be a nicer language with native defer. Working directly with C APIs (which is one of the main reasons to use C++ over Rust or Zig these days) would greatly benefit from it.

Re: Defer available in gcc and clang

#80

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.

> I still stay with C89 because I know it will be portable anywhere With respect, that sounds a bit nuts. It's been 37 years since C89; unless you're targeting computers that still have floppy drives, why give up on so many convenience features? Binary prefixes (0b), #embed, defined-width integer types, more flexibility with placing labels, static_assert for compile-time sanity checks, inline functions, declarations…

To be honest I have similar reservations.

The one huge advantage of C is its ubiquity - you can use it on the latest shiny computer / OS / compiler as well as some obscure embedded platform with a compiler that hasn't been updated since 2002. (That's a rare enough situation to be unimportant, right? /laughs in industrial control gear.)

I'm wary of anything which fragments the language and makes it inaccessible to subsections of its traditional strongholds.

While I'm not a huge fan of the "just use Rust" attitude that crops up so often these days, you could certainly make an argument that if you want modern language features you should be using a more modern language.

(And, for the record, I do still write software - albeit recreationally - for computers that have floppy drives.)

Post reply on HN