I think it's great that the authors are working on this. RAII is one of the best things about C++, and I'm excited for similar functionality in C. GCC's __cleanup__ is a poor substitute for a fully-baked addition to the language. From skimming through the paper, it looks like there's an open discussion about the 'guard' keyword and scoping. I know that the scoping rules are tricky. Would it make sense for defer state…
A Defer Mechanism for C
231–240 of 248 posts
Re: A Defer Mechanism for C
#232Earlier quoted context omitted.
> In your last four code blocks, you demonstrated three alternate ways to implement the functionality you want without defer. My, I didn't think it was possible to miss the point like that. Are you even arguing in good faith? Let's examine for a moment the 3 other alternatives. First, we get the "repeat ourselves" problem: when I have several exit points, I must clean up at each exit . And if I edit the code in any w…
You have accused me of arguing in bad faith twice in one post. This is insulting, not to mention against the HN rules ("assume good faith"). Clearly we disagree on whether a syntax change is minor. But first let me repeat the point I made that you ignored in between your accusations: it really is just syntax. Of the four examples in the second part of your post, if we assume defer is implemented like attribute cleanu…
It's really not. When the impact of "syntax" are non-local like that, it's more than syntax. A compiler would handle this beyond the parsing stage. At the very least, it would seriously massage the AST to remove `defer` from it.
> if we assume defer is implemented like attribute cleanup and fix up the compile errors, your first and fourth example compile to the identical assembly code:
This is to be expected: they ultimately do the same thing, and optimisers are known to do significant, non-local transformations to the code.
> move the "business logic" into a separate function, one that takes the necessary resources as arguments.
So now I have a function with (likely) too many arguments, that's used only once, and my eyes have to jump around to get to it (or I have to reach for the F2 key). The pyramid may be more visible, but that's a meagre advantage.
> In my opinion the nested if style is better than using defer because it's completely linear with no backward jumps.
Not even a criterion in my book. I suspect you're having an overly operational mindset. A mindset I suspect has held the whole field back a couple decades. Don't think of it like a backward jump. It's meant to be viewed as deferred execution, triggered by scope exit.
> you can hardly complain about cleanup code being far from init code because the whole resource handling function is less than 20 lines of code
That was an example, dummy. In real code, I'd have more than 3 things to initialise, and their initialisation might not be as trivial (or as repetitive) as what I've shown here. That's when I really want to read the code from top to bottom, with concerns packed together. Defer/cleanup lets me do that. The other solutions, less so.
Re: A Defer Mechanism for C
#233Earlier quoted context omitted.
It’s even more explicit to just call your cleanup routines manually, so by that logic “defer” is inferior to existing methods of handling cleanup in C
subroutine calls requires implicit allocation and deallocation of stack frames. Real Programmers™ use goto and manage the stack by hand.
Could u point to an example of programmers doing this ?
Re: A Defer Mechanism for C
#234I just did a search and it seems https://crates.io/crates/cc comes close. If only an IDE could do the job automatically when it finds .c files in the project. Even better, it should find and install a local compiler when needed (C or any other).
Re: A Defer Mechanism for C
#235Earlier quoted context omitted.
> defer just changes the problem from forgetting to write free to forgetting to write defer. That's the case only the first time you write code: { foo *f = new_foo(); // step 1 /* lots of code */ // step 3 free(f); // step 2 } vs { foo *f = new_foo(); // step 1 defer free(f); // step 2 /* lots of code */ // step 3 } Sure, in both cases you can forget step 2. But what about review ? With defer, the init and cleanup co…
I think this example demonstrates the opposite of what you intended. Defer doesn't give you anything that you can't already do. In your last four code blocks, you demonstrated three alternate ways to implement the functionality you want without defer. Defer is just a slightly different, arguably nicer fourth way to implement the same code. Language features should be orthogonal. A new language feature should add some…
Well, that's the whole point of syntactic sugar.
Not that it gives you something you can't already do, but that it gives you a succint and better way to do it.
>Language features should be orthogonal. A new language feature should add something that is not possible or extremely painful to do with the existing language features.
I beg to differ, based on your definition of "extremely painful". Many kinds of syntactic sugar are welcome, even when the previous native solution wasn't "extremely painful" but e.g. just tedious or error prone.
Re: A Defer Mechanism for C
#236Earlier quoted context omitted.
The specified label is what makes goto no-local. You need to check the whole codebase to find out where you'll land. By your definition only [1] "come from" would be non-local. [1] https://en.wikipedia.org/wiki/COMEFROM
> the whole codebase You can't goto out of a function, and you know there's exactly one such label inside it. If goto isn't local, then neither are function calls, since the function could be defined anywhere in the codebase.
You can with a goto expression and a label address available - though the behavior is undefined in C, so bets are off.
And you can with longjump/setjump more explicitly.
Re: A Defer Mechanism for C
#237I’ve always considered “defer” an inelegant kludge in comparison to RAII for automatic cleanup of resources. It’s surprising that the C standards committee is considering adding that to the language. Then again, nearly none of the syntactic C features post-C89 have been very compelling or widely adopted.
RAII is a special case of defer, due to how it abuses constructors and destructors to hook into the points of entering and exiting scope. You could write a RAII implementation in terms of defer but not the other way around. RAII doesn't help with a generic pair of init and deinit functions, such as malloc() and free() for example, unless you wrap your mallocs into "memory objects" or something. You can't do anything…
Re: A Defer Mechanism for C
#238Re: A Defer Mechanism for C
#239Please just standardize the already existing attribute((cleanup)) mechanism which is already being used by lots of Linux software. This new mechanism is incompatible while bringing no benefits.
This is... wild. I had no idea attrribute((cleanup)) was a thing in CNU C. Did the C folks finally discover the concept of a destructor? What's the point of resisting C++ so adamantly if they're going to introduce the same features with an awful nonstandard syntax in an ad-hoc manner anyway?
Re: A Defer Mechanism for C
#240Earlier quoted context omitted.
> the whole codebase You can't goto out of a function, and you know there's exactly one such label inside it. If goto isn't local, then neither are function calls, since the function could be defined anywhere in the codebase.
> You can't goto out of a function You can with a goto expression and a label address available - though the behavior is undefined in C, so bets are off. And you can with longjump/setjump more explicitly.