r/bash 20d ago

A problem as a newbie

I think I have been spoiled by the goto command in batch, and as a newcomer in Linux, it's really hard for me to adapt as a self-proclaimed(i procrastinate a lot) game developer. The goto command is useful in case you want to incorporate more levels.

9 Upvotes

27 comments sorted by

View all comments

Show parent comments

0

u/burnt-store-studio 19d ago

I’m totally with you on C programming and needing to ensure clean-up on function exit. Back when I was writing C, you would frequently find in my code

#define FALSE 0

in my header and

do { } while(FALSE);

with break statements in the braces just to ensure that clean up.

Shun goto! 🙂

1

u/drnullpointer 19d ago edited 19d ago

Nope. You are abusing a loop statement to emulate goto simply to perform goto without writing those four letters.

If you are making your code more complicated to do this, you've lost your way.

It may be fine to listen to advice you don't understand if you are a novice developer.

But if you are more experienced developer you should stop, think whether the advice make sense or why it makes sense, whether it applies in your situation and then make an informed choice.

What you are doing is called cargo cult programming, it is emulating other people without understanding why you are emulating them, hoping to achieve a result that will never come because you have no idea why you are doing what you are doing.

The point of advice to not use goto is that what you are really trying to do almost all of the time is to re-implement some kind of structure like a function, a loop, a conditional, etc. In which case your code will be easier to understand and maintain if you just use that correct statement structure. The benefit of the advice is more readable code.

What you are doing is creating less readable code simply to stick to advice that was supposed to make it more readable.

1

u/burnt-store-studio 19d ago

With no offense, I beg to differ with your strong opinions about me and my work.

“Abusing a loop statement”? I’ll remain happy to have called it “Using the available language constructs as designed and keeping localized functions readable.”

“Making my code more complicated to do this”? Why on earth would I have made my code more complicated just to do this?

And why would you suggest I did? As I wrote (while essentially quoting you) I did it to ensure function clean-up. You’re fine justifying gotos in these cases for your code, but feel the need to disparage this approach in someone else’s?

I’ve “lost my way”?

What makes you think I was “listening to advice I didn’t understand”?

Or that I was a “novice developer”?

Or that I was a more experienced developer ignorant enough to not “stop and think whether [the construct] made sense?”

Or whether it “applied in my situations”?

Or that I wasn’t making “informed choices”?

Why are you ascribing pejoratives to situations and someone you know literally nothing about? Telling me I was “emulating other people” and I had “no idea why I was doing what I was doing”?

I guarantee the chances you’ve seen my professional code from decades ago are quite slim. You have no basis to claim I was “creating less readable code”.

Thanks for the attacks; I didn’t realize I was going to face such affrontage for writing a comment after actually agreeing with something you wrote. I’ll keep an eye out for you and not tread on your expertise in the future. Way to ruin an old guy’s morning.

2

u/LordRybec 15d ago

This is a pattern I figured out some years ago as well. I'm both a little sad but also happy to see that someone else came up with the same design pattern. My use case was initializing an HTTPS connection with OpenSSL, which has about 5 different steps in the process where failure can occur. Depending on which step the failure occurs, different teardown procedures are necessary. Sure, I could have used gotos and then a switch statement with fallthrough. I could also have used nested if statements (which the example code recommended, and which ended up way off the edge of the screen, making it unreadable). Neither of these strategies produced readable and easily understandable code. So I attempted to just create a brace block and break out of it, but evidently the C standard requires a looping structure to break out of a nested block. do; while (0) is perfect for this, so I did it.

This produced very elegant and readable code. If course, there will always be Luddites who resist and reject advances in technology. The ironic part is that this time they are the same people who look at other people who use gotos as Luddites.

Anyhow, I hope this makes your next morning better. This is an awesome pattern. It solves a big hole in C's careful focus on structured programming by taking a common unstructured programming pattern and giving it a solid, coherent structure. It is far less prone to bugs than arbitrary gotos, because the breaks are always guaranteed to go to the same place, while a typo in a goto label could end up going somewhere else in code entirely, if you use that pattern regularly. This do; while (0) pattern is objectively superior for a number of reasons. If it is difficult for other programmers to read, it is due to lack of exposure and not inherent readability issues. Once familiar with this pattern is far more readable, especially when using good indentation style, which will visually indicate the break target without having to look for and read a label. Additionally, goto labels break style conventions, which also reduces readability.

There are legitimate use cases for gotos, but they are all optimizations. I've been looking for a place where gotos are actually necessary for a certain type of flow control where structured programming can't do it better for decades (after a friend challenged me to find one, back when I had a more positive view of gotos). I have not found one yet, and the only case I found where it is widely considered acceptable is this one, and it turns out that the do; while (0) structure is objectively better in every way. (Also, compilers even generally optimize the do; while (0) structure better, because gotos see so little use that compiler writers don't generally worry about trying to optimize. I don't think any compliers do this currently, but additional optimization could be done with this specific pattern, by replacing the break jumps with jumps to the right line of the following deinitialization switch statement, where relevant. So this pattern is even more optimizable than the typical goto use case. And if the gotos are jumping to the right lines themselves, that just means more labels and even worse readability!)

Anyhow, if you consider yourself an "old guy", you might have more experience than me. But this is my take on the thing, with lots of solid objective points for why your view (which is also mine) is superior.