Live data from Hacker News

C: Simple Defer, Ready to Use

gustedt.wordpress.com

121–130 of 157 posts

Re: C: Simple Defer, Ready to Use

#121
post #92

One big flaw in Go-style `defer` is that error handling and scoping are an afterthought, and it's disappointing to see this is not improved upon in this proposal (at least as I understand the proposal). I do think this matters in practice. If I have a `func whatever() error` IME it's a common to accidentally do something like `defer whatever()` without catching handling the error. To work around that you'd need to do…

__attribute__((cleanup)) cleans up on scope exit, unlike go.

Re: C: Simple Defer, Ready to Use

#123

Earlier quoted context omitted.

> I really, really do not like what that could do to the readability of code if it was used liberally. > It's like GOTOs, but worse, because it's not as visible. > C++'s destructors feel like a better/more explicit way to handle these sorts of problems. But what C++ gives you is the same thing: > It's like GOTOs, but worse, because it's not as visible. ! The whole point of syntactic sugar is for the machinery to be h…

> The whole point of syntactic sugar is for the machinery to be hidden And when the machinery fails, you'll not only have the machinery to debug, but the syntactic sugar too.

Yeah, compiler bugs happen.

Re: C: Simple Defer, Ready to Use

#124
post #83
post #37

Earlier quoted context omitted.

To be fair you're not communicating very well — there are no trampolines being used here because the call site is directly in the same function, so no trampoline is needed with already being in the correct stack frame. (And also on -O1 and higher the entire call is optimized out and the nested function inlined instead.)

I feel that uecker went above and beyond the call of duty by including a godbolt link in their first comment which shows the full assembly-language implementation of this behavior by GCC without using an executable stack, with syntax highlighting, and full C source for reproducing the behavior on your own machine. I don't see how anything they could possibly have written as a comment could be clearer or more convinci…

I edited the comment to add the link a couple of minutes later, so maybe it was missed.

Re: C: Simple Defer, Ready to Use

#125
post #97

I don't think "you can implement this slightly modified version of the proposal in GCC macros" is a good reason to change the defer proposal. It doesn't work in clang¹ or any other non-GCC C implementation, a trailing semicolon after the close brace is an ugly wart, and saying "if you want to implement this all you have to do is implement [[gnu::cleanup]] and nested local functions" is presumably much more work for o…

Why do you think you need executable stacks for nested functions? I don't know what GCC is doing, but functional programming languages usually 'compile away' the nesting of functions fairly early, see https://en.wikipedia.org/wiki/Lambda_lifting Update: Oh, I see, it's because GCC doesn't want to change how function are passed around ('function pointers' in C speak), so they need to get creative. Functional languages…

GCC creates trampolines only when it needs the address of the nested function, which it does not in this case (formally it does but not really). Also new version can place the trampoline on the heap (-ftrampline-impl=heap) and then you also need no executable stack. I wide pointer would be better though.

Re: C: Simple Defer, Ready to Use

#127

I really, really do not like what that could do to the readability of code if it was used liberally. It's like GOTOs, but worse, because it's not as visible. C++'s destructors feel like a better/more explicit way to handle these sorts of problems.

GOTO is not necessarily a bad thing to begin with. Not to mention this does not really resemble GOTO.

Re: C: Simple Defer, Ready to Use

#128
post #58

Earlier quoted context omitted.

How do you write C code that needs to do this (set up several resources, and clean only some of them up depending on where the function returns) so that it’s easy to follow?

When constructing an object in C, we may need some permanent sub-objects, and some temporary objects. If we only need permanent sub-objects, then we set those up gradually, and build an error path in reverse order (with gotos or with the arrow pattern); upon success, the sub-objects' ownership is transferred to the new super-object, and the new super-object is returned, just before the error path is reached. Otherwis…

So, you recommend using goto, which indeed is the only available mechanism.

Re: C: Simple Defer, Ready to Use

#129
post #84
post #76

Earlier quoted context omitted.

The major source of bugs in C is located on string.h, and nothing has been made in 50 years to fix that. Really fix, not mitigations with their own gotchas.

There have been things done to try to fix that, see "strcpy_s" and other related functions. Visual Studio even considers use of the classic string functions (like "strcpy") to be a compiler error. You need to define a specific macro before you are allowed to use them.

You missed my second paragraph.

Re: C: Simple Defer, Ready to Use

#130
post #92

One big flaw in Go-style `defer` is that error handling and scoping are an afterthought, and it's disappointing to see this is not improved upon in this proposal (at least as I understand the proposal). I do think this matters in practice. If I have a `func whatever() error` IME it's a common to accidentally do something like `defer whatever()` without catching handling the error. To work around that you'd need to do…

> One big flaw in Go-style `defer` is that error handling and scoping are an afterthought....

Like many other things in Go's approach to language design, still better than using plain old C, though.

Post reply on HN