Live data from Hacker News

A Defer Mechanism for C

gustedt.wordpress.com

181–190 of 248 posts

Re: A Defer Mechanism for C

#181
post #2

Despite being convenient,I have the feeling that it might be a bad idea. One of the key interest of C compared to more recent languages is that everything is explicit. With a finger you can follow the code as it runs and know exactly what is going on and when exactly. At the opposite, there is c++ that does a lot of things automagically. And it is often hard to understand why you suddenly get a segfault out of blue,…

I've heard this comment more than once. What we are trying to accomplish is to collocate the resource acquisition code with the acquisition release code. This does mean that the release code is removed when where the release occurs (for example, at every location a function returns. However, this is not without precedence in C. For example, just look at the for loop: for (clause1; expression2; expression3) statement…

I would argue that the C for loop is a rather awkward construct. It's found its way in many languages, so I think most people are used to its idiosyncrasy but it's not great if you try to take a fresh look at it.

I think the best defense of this syntax is that it makes writing basic iteration a bit nicer without having to add boilerplate (the iconic `for (i = 0; i < n; i++)`) but then I would argue that the real problem is that C is severely lacking in the iteration department and this is a rather obvious hack (that languages like Javascript felt the need to copy wholesale, for some insane reason).

Re: A Defer Mechanism for C

#182
post #88
post #69

Earlier quoted context omitted.

Only if you include dynamically sized arrays, which are deprecated because of their problematic allocation behaviour.

I don't believe that VLAs are actually deprecated as such, but have been moved to an "optional" feature for implementation in C11. There's a feature macro to check, __STDC_NO_VLA__, but I don't think the feature is actually disappearing from the standard any time soon.

I wonder what is a good use for VLAs btw. I used it for a string padding function to create the padding with a simple loop before a call to strjoin. Is that a bad idea or a legitimate use case?

Re: A Defer Mechanism for C

#185
post #74

Earlier quoted context omitted.

I would tend to agree with you. Unfortunately this proposal is for much more than just block scope cleanup. This proposal contains a specification for complete stack unwinding in C. It doesn't just specify defer, but also panic and recover, which jumps between functions and cleans up guard blocks across stack frames. It's essentially exceptions for C. This is frankly horrifying and I can't believe the C standards com…

Doing other things in the proposal is no argument against having an attribute((cleanup)) compatible syntax for the part that overlaps. Also, the defer syntax they're proposing seems nicer in terms of syntactic sugar (no need for a stub function), but at the same time the semantics seem ... weird. Having it tied to a variable makes more sense, and sidesteps a whole bunch of weird situations (like loops with defer stat…

In the contrary, I find it really weird to bind all cleanup code to some kind of object with constructors and destructors. People seem to have gotten so used to this ... I think that for C it is much more natural to have a control structure in the language for this.

Re: A Defer Mechanism for C

#186
post #90
post #71

Earlier quoted context omitted.

You’re missing the point. The two are alike in that something significant is happening that you as the programmer did not explicitly tell it to do. The specific mechanism really isn’t an important distinction here.

There is no guarantee when a Java finalizer will run, whereas a C++ destructor is guaranteed to run based on the code that you write. That's a big difference which has practical implications, using something with non-guaranteed behaviour as an example of why something with guaranteed behaviour is hard to predict seems like a misunderstanding.

Of course it has practical implications and is harder to predict, but neither of those are what this conversation is about.

Re: A Defer Mechanism for C

#188

Earlier quoted context omitted.

That solution doesn't work if you malloc up a structure and stick other things that need cleanup and won't be aware of the context (example: a file descriptor) inside.

Maybe, maybe not. If your context has a list of things to free, it can also have a list of things to close. Or whatever you want. Many libraries do stuff like this and call the context creation/deletion lib_init/ lib_shutdown.

It sounds an awful lot like such a context mechanism needs dynamic allocations. Something like the GNU cleanup attribute or a proposal like defer, or C++ RAII, can do that as a stack unwind, without the need for heap.

Re: A Defer Mechanism for C

#189

Earlier quoted context omitted.

Based on committee discussion, I think it is unlikely we will attempt to capture the values. The capture will most likely be done by reference. This case of the defer in the loop is frequently cited, probably because it is a problematic case. However, I looked at a lot of real code and the only case I found of resources being allocated in a loop they were allocated at the beginning of the loop and deallocated at the…

The simple solution to me seems to be to just ban use of loops hierarchically between a defer statement and a guard block. The guard block should definitely be kept as using scope seems like it confuses and complicates the notion of scope; for instance, it seems like a footgun if "if(some condition that turns out to be always true) {blah blah}" can't be refactored into "blah blah". Also, using scope seems to make it…

That is effectively one of the options that is under discussion. One of the advantage of the approach with defer is really that everything happens in the open and all uses that one would want to classify as misuse can easily be flagged by the compiler.
Post reply on HN