Live data from Hacker News

C: Simple Defer, Ready to Use

gustedt.wordpress.com

111–120 of 157 posts

Re: C: Simple Defer, Ready to Use

#112
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…

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…

Well, there you get that I don't believe in letting certain people own ideas and then stick to them as if they were given revelation from on high about how things should work. The distinctive thing about goto that breaks structured programming, to the point that functions as we think of them today can't even exist in such an environment, is the ability to jump arbitrarily.

I'm way less worried about uses of goto that are rigidly confined within some structured programming scope. As long as they stay confined to specific functions, they are literally orders of magnitude less consequential than the arbitrary goto, and being an engineer rather than an academic, I take note of such things.

I don't ask Alan Kay about the exact right way to do OO, I don't ask Fielding about the exact right way to do REST interfaces, and I don't necessarily sit here and worry about every last detail of what Dijkstra felt about structured programming. He may be smarter than me, but I've written a lot more code in structured paradigms than he ever did. (This is not a special claim to me; you almost certainly have too. You should not ignore your own experiences.)

Re: C: Simple Defer, Ready to Use

#113
post #73

I once worked on a student robotics project where if you didn't gracefully shut down the connection to a specialized camera, it had a significant chance of physically bricking the camera. We were using C++ and essentially instrumented code review processes, despite being a student group, to ensure nothing was ever called in a way where the destructor wouldn't be called - and broke out vision processing into a separat…

Yikes. So the OOM Killer bricks your camera then!?!

Re: C: Simple Defer, Ready to Use

#114

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

> number 1 issue I find myself having when switching from C++ to C is missing RAII That's because you've become complacent; you've gotten used to the false comfort of destructors. C++ destructors promise that you can ignore object destruction in business logic, and that's a false promise. Assume you have a function that already has a correct traditional (cascading gotos, or arrow pattern) exit path / error path. Assu…

See but the issue is that humans are not perfect, and time is usually a resource.

Without defer like mechanisms objects get leaked, mutexes held after return, etc...

In a perfect world everything could be perfectly explicit as infinite time and energy has gone into ensuring nothing is forgotten and everything / every code path is well exercised.

Even then, scoped based resource acquisition / releasing still feels more ergonomic to me.

Re: C: Simple Defer, Ready to Use

#115

Earlier quoted context omitted.

Nearly every modern language supports defer in some sense. Unless you are talking about RAII hiding the defer, but that's not the case with a custom Defer type or similar that takes a closure in the constructor. Defer is a way better solution than having to cleanup in every single failure case.

> cleanup in every single failure case you're only tempted to clean up [fully] in every single failure case if you don't know how to implement cascading gotos or the arrow pattern.

I'll be honest that you are in the minority here.

goto is widely considered an anti-pattern and so is the arrow pattern.

Re: C: Simple Defer, Ready to Use

#116

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…

I don't think they're advocating not doing defer in C? They're saying you can backport the functionality if needed, or if you want to start using it now.

They're recommending changes to the proposal though, such as requiring a trailing semicolon after the close brace. It also changes the syntactical category of the defer statement, though it's not clear to me what that actually affects.

Re: C: Simple Defer, Ready to Use

#117
post #110

Earlier quoted context omitted.

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

I struggle with how you claim my "analysis is wrong", and then basically reiterate my entire point. I know it's not that badly written; other people got it just fine and complain about what it actually does say. The modern goto is not the one he wrote about. It is tamed and fits into the structured programming paradigm. Thus, ranting about goto as if it is still the 1960s is a pointless waste of time. Moreover, even…

> The modern goto is not the one he wrote about. It is tamed and fits into the structured programming paradigm.

No, it doesn't, not the goto of C or C++ (which tames it a smidge because it has to). That's the disconnect you have. It's not fine just because you can't go too crazy and smash other functions with it anymore. You can still go crazy and jump into the middle of scopes with uninitialized variables. You can still write irreducible loops with it, which I would argue ought to be grounds for the compiler to rm -rf your code for you.

There are tame versions of goto--we call them break, continue, and return. And when the C committee discussed adding labeled break, and people asked why it was necessary because it's just another flavor of goto, I made some quite voluminous defense of labeled break because it was a tame goto, and taming it adds more possibility.

And yes, the tame versions of goto violate Dijkstra's vision. But I also don't think that Dijkstra's vision is some sacrosanct thing that must be defended to the hilt--the tame versions are useful, and you still get most of the benefits of the vision if you have them.

In summary:

a) when Dijkstra was complaining about goto, he would have included the things we call break, continue, and early return as part of that complaint structure.

b) with the benefit of decades of experience, we can conclude that Dijkstra was only partially right, and there are tame goto-like constructs that can exist

c) the version of goto present today in C is still too untamed, and so Dijkstra's injunction against goto can apply to some uses of it (although, I will note, most actual uses of it are not something that would fall in that category.)

d) your analysis, by implying that it's only the cross-function insanity he was complaining about, is wrong in that implication.

Re: C: Simple Defer, Ready to Use

#119
post #110

Earlier quoted context omitted.

I struggle with how you claim my "analysis is wrong", and then basically reiterate my entire point. I know it's not that badly written; other people got it just fine and complain about what it actually does say. The modern goto is not the one he wrote about. It is tamed and fits into the structured programming paradigm. Thus, ranting about goto as if it is still the 1960s is a pointless waste of time. Moreover, even…

> The modern goto is not the one he wrote about. It is tamed and fits into the structured programming paradigm. No, it doesn't, not the goto of C or C++ (which tames it a smidge because it has to ). That's the disconnect you have. It's not fine just because you can't go too crazy and smash other functions with it anymore. You can still go crazy and jump into the middle of scopes with uninitialized variables. You can…

"You can still go crazy and jump into the middle of scopes with uninitialized variables."

It is difficult when speaking across languages, but in many cases, no, you can't.

https://go.dev/play/p/v8vljT91Rkr

C isn't a modern language by this standard, and to the extent that C++ maintains compatibility with it (smoothing over a lot of details of what that means), neither is it. Modern languages with goto do not generally let you skip into blocks or jump over initializations (depending on the degree to which it cares about them).

The more modern the language, generally the more thoroughly tamed the goto is.

Post reply on HN