Live data from Hacker News

C: Simple Defer, Ready to Use

gustedt.wordpress.com

41–50 of 157 posts

Re: C: Simple Defer, Ready to Use

#41
post #4

Do defers get processed if an exception is thrown? I know C doesn’t have exceptions, but real world C code often interacts with C++ code. So it is necessary imo to define that interaction. In C++ we have something pretty similar already in the form of Folly ScopeGuard (SCOPE_EXIT {}).

GCC has the __cleanup__ attribute which works in conjunction with exceptions in C to provide an RAII mechanism.

No it doesn't; C functions don't set up appropriate registrations with the C++ exception / stack unwinding systems, thus C functions are simply skipped over on the way up towards the nearest exception handler.

__attribute__((cleanup(…))) is purely a scope-local mechanism, it has absolutely nothing to do with exceptions.

Re: C: Simple Defer, Ready to Use

#42

Unfortunately the first thing I see is a giant ad scroll down over the header blocking the entire viewport on my phone, so immediately hit the back button. Are all personal blogs automatically monetized now?

Free sites on WordPress.com are:

https://wordpress.com/support/no-ads/

Re: C: Simple Defer, Ready to Use

#43
post #37
post #32

Earlier quoted context omitted.

The trampolines are not generated in this case.

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.)

Fair, I was not explaining why the statement was wrong. Anyhow, the trampoline is not related to the call site being in the same function but whether a pointer is generated to the nested function and escapes. Nested functions in general do not need trampolines or executable stack.

Re: C: Simple Defer, Ready to Use

#44
post #16
post #14

Earlier quoted context omitted.

Dijkstra was not wrong. Modern programmers are wrong in thinking that the goto that they use is what Dijkstra was talking about, merely because of the fact it happens to be called the same thing. I mean, I get how that can happen, no sarcasm, but the goto Dijkstra was talking about and what is in a modern language is not the same. https://jerf.org/iri/post/2024/goto/ The goto Dijkstra is talking about is dead. It liv…

Or the tl;dr in modern parlance Dijkstra was railing against the evils of setjmp.

No, even setjmp/longjmp are not as powerful or dangerous. The issue is not the locality of the jump, but the lack of any meaningful code structure enforced by the language. Using setjmp and longjmp properly still saves and restores context. You still have a function call stack, a convention for saving and restoring registers, locally scoped variables, etc. Though, using setjmp/longjmp improperly on some platforms might come close, since you're well into undefined behavior territory.

Parent is correct that this doesn't really exist outside of assembly language anymore. There is no modern analogue, because Dijkstra's critique was so successful.

Re: C: Simple Defer, Ready to Use

#45

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.

I don't mind destructors but I don't understand your insistence that they're significantly better than defer for visibility: they're invisible and invoke a distant jump to some bit of code which might not even be in your codebase; defer is "right there" (and with proper editor support could even be made to look like it happens at the end of the function instead of where it's declared). I think they're both fine for their respective languages.

Re: C: Simple Defer, Ready to Use

#46
post #27

Does C really need this? Do languages need to grow in this way? The overriding virtue of C is simplicity.

Yes it does, and numerous projects already use variants of this trick.

Including Linux kernel https://github.com/torvalds/linux/blob/master/include/linux/...

Re: C: Simple Defer, Ready to Use

#47
post #14

Earlier quoted context omitted.

gotos can be used without shame. Dijkstra was wrong (in this rare case). defer is cleaner, though.

Dijkstra was not wrong. Modern programmers are wrong in thinking that the goto that they use is what Dijkstra was talking about, merely because of the fact it happens to be called the same thing. I mean, I get how that can happen, no sarcasm, but the goto Dijkstra was talking about and what is in a modern language is not the same. https://jerf.org/iri/post/2024/goto/ The goto Dijkstra is talking about is dead. It liv…

The interpretation of Dijkstra's sentiment in your blog post is plain wrong.

His paper [1] clearly talks about goto semantics that are still present in modern languages and not just unrestricted jmp instructions (that may take you from one function into the middle of another or some such). I'd urge everyone to give it a skim, it's very short and on point.

[1] https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.p...

Re: C: Simple Defer, Ready to Use

#48
post #14

Earlier quoted context omitted.

gotos can be used without shame. Dijkstra was wrong (in this rare case). defer is cleaner, though.

Dijkstra was not wrong. Modern programmers are wrong in thinking that the goto that they use is what Dijkstra was talking about, merely because of the fact it happens to be called the same thing. I mean, I get how that can happen, no sarcasm, but the goto Dijkstra was talking about and what is in a modern language is not the same. https://jerf.org/iri/post/2024/goto/ The goto Dijkstra is talking about is dead. It liv…

Your analysis is wrong. Dijkstra was a big proponent of structured programming, and the fundamental thesis of his argument is that the regular control flow structures we're used to--if statements, loops, etc.--all represent a tree-based data structure. In essence, the core argument is that structured programming allows you to mentally replace large blocks of code with black boxes whose exact meanings may not be important.

The problem with GOTO, to Dijkstra, is that it violates that principle. A block can arbitrarily go somewhere else--in the same function, in a different function (which doesn't exist so much anymore)--and that makes it hard to reason about. Banning GOTO means you get the fully structured program that he needs.

(It's also worth remembering here that Dijkstra was writing in an era where describing algorithms via flowcharts was common place, and the use of if statements or loops was far from universal. In essence, this makes a lot of analysis of his letter difficult, because modern programmers just aren't exposed to the kind of code that Dijkstra was complaining about.)

Since that letter, modern programming has embraced the basic structured programming model--we think of code almost exclusively of if statements and loops. And, in many language, goto exists only in extremely restricted forms (break, continue, and return as anything other than the last statement of a function). It should be noted that Dijkstra's argument actually carries through to railing against the modern versions of break et al, but the general program of structured programming has accepted that "early return" is an acceptable deviation from the strictly-single-entry-single-exit that is desired that doesn't produce undue cognitive overhead. Even where mind-numbing goto exists today (e.g., C), it's similarly largely used in ways that are similar to "early return"-like concepts, not the flowchart-transcribed-to-code-with-goto-as-sole-control-flow style that Dijkstra is talking about.

And, personally, when I work with assembly or LLVM IR (which is really just portable assembly), I find that the number one thing I want to look at a very large listing is just something that converts all the conditional/unconditional jumps into if statements and loops. That's really the main useful thing I want from a decompiler; everything else as often as not just turns out to be more annoying to work with than the original assembly.

Re: C: Simple Defer, Ready to Use

#49

I'm a strong believer that if C had defer, many bugs would disappear. The number 1 issue I find myself having when switching from C++ to C is missing RAII (Main C++ way of implementing defer).

I agree about missing RAII when switching away from C++ but it seems like defer cleans up after enclosing function exits while RAII cleans up when object goes out of scope, which is more fine-grained. Maybe I'm misunderstanding exactly when defer would clean up but it seems more like a safety feature. As people pile more stuff into the function the cleanup would be deferred more and more while RAII encapsulates the management right where you need it, e.g. exiting a loop or something.

Re: C: Simple Defer, Ready to Use

#50
post #30

Earlier quoted context omitted.

i like how the contraction it’s and abbreviation T’is are anagrams

It is not T'is, it is Tis. No apostrophe.

The apostrophe is in the wrong spot, but 'tis is the correct spelling, and the only one I've ever seen.
Post reply on HN