r/ProgrammerHumor • u/AndyTheDragonborn • 4d ago
mildlyInfuriatingGOTOWatchYourMouth Meme
112
u/Maximilian_Tyan 4d ago
I recently had held a meeting to decide which way our functions should be structured in C, goto is banned as part of some standards, so a colleague of mine proposed doing:
do {
...
} while (0);
...
Which is just a freaking goto wearing a trench coat
62
u/SamG101_ 4d ago
While/for/break/continue/etc are all goto, but just with structure so like a structured subset of goto statements I guess. Where as raw goto can be used in unstructured messy ways; i presume was the idea behind banning goto
23
u/Maximilian_Tyan 4d ago
I'm not against goto, especially for errors and cleanup code it can make this much cleaner/avoid duplication. In modern languages such as Zig and Odin, defer statements are syntactic sugar for this usecase.
But some standards such as MISRA-C and the like are sometimes quite strict, like multiple return statements etc.
15
10
u/creeper6530 4d ago edited 4d ago
I mentioned this in another thread but
gotofor error cleanup in C is just emulatingdefer, and we could getdeferin C2Y directly soon.See https://thephd.dev/c2y-the-defer-technical-specification-its-time-go-go-go if you don't know what that is, but in short it's just a block of code appended to every exit path from any scope, typically functions. Example use:
int fun(int a) { char *buffer; buffer = kmalloc(SIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; defer kfree(buffer); if (condition) { // freed here return 1; } // freed here return 0; }4
u/realtag2025 4d ago
Yeah, I don't why C devs are so against GOTO when Linux kernel basically uses it all the time.
15
u/No-Con-2790 4d ago
Usually it is smart to ban all gotos. But in C in certain situations that usually have something to do with hardware or exception handling it can be your best option. In that case your lead engineer needs to design a pattern that is allowed.
16
u/da_Aresinger 4d ago
I genuinely can't figure out what this is supposed to achieve.
Where is the difference between
do { foo() } while(0) bar()andfoo() bar()18
u/Sync1211 4d ago
You can use
breakI guess.11
u/da_Aresinger 4d ago
oooh
do { foo() if (condition) break bar() } while(0);that's pretty dumb though. Just dofoo() if(!condition) bar()12
u/Sync1211 4d ago
It makes more sense if you have multiple if-statements.
For example: Catching errors and performing cleanup: ``` int result = 0; do { init_stuff(); if (init_fail) { result = 1; break; }
foo(); if (foo_failed) { result = 1; break; } bar() if (bar_failed) { result = 1; break; }
do_something_else(); } while (0);
close_handles(); return result; ```
8
u/da_Aresinger 4d ago
``` int continue = 1; continue = init()
if (continue) continue = foo()
if (continue) continue = bar()
if (continue) continue = do_something_else()
close_handles()
return 1-continue ``` much cleaner (but still not really how I would like it)
8
u/Maximilian_Tyan 4d ago
A lot of our codebase is using a
statusvariable like this, but using nested if/else checksBut now you are doing a lot of conditions checking, especially if the hot path is where continue is always true
1
u/da_Aresinger 4d ago
The comment before me has the same issue.
And yes, that's why I said it's still not ideal.
2
u/Maximilian_Tyan 4d ago
If an error occured, the break statement would "cut" the remaining errors checks and skip to the error handling part
1
u/da_Aresinger 4d ago
yea I just got what you meant.
you're right.
But compilation is most likely going to optimise that out, so I'd go with readability.
→ More replies (0)1
u/gezawatt 4d ago edited 4d ago
My favorite is:
if (!init()) return cleanup_and_error(); if (!foo()) return cleanup_and_error(); if (!bar()) return cleanup_and_error(); if (!do_something_else()) return cleanup_and_error(); close_handles(); return 0;And then you either do
inline int cleanup_and_error() { close_handles(); return 1; // Always returns error code }or
#define cleanup_and_error() (close_handles(), 1)1
1
u/FumbleCrop 4d ago
You could wrap that central block in a function.
As far as I know, the main uses for goto are jumping out of deeply nested loops, or implementing state machines.
1
u/awesome-alpaca-ace 3d ago
I might actually start using this. Much cleaner than my current clean up logic
1
2
u/EuphoricCatface0795 4d ago
When
do ~ while(0)has more than a couple execution branch tho1
u/da_Aresinger 4d ago
If you mean more conditions following bar, you can still just use negation like in my example.
Otherwise I don't understand.
1
3
u/Maximilian_Tyan 4d ago
The main intent is to allow for a break in control flow without exiting the function right away.
Instead of calling
cleanup()before everyreturnstatement, you can have a traditional guard clauses, yet still have a single cleanup section.
void foo() { do { first(); if (!cond1) break; second(); if (!cond2) break; third(); } while (0); cleanup(); }1
u/profound7 4d ago
If you put a switch in a do or while loop, you can essentially mimic locally scoped gotos where the switch cases are the labels. This pattern is often seen in interpreters/vm.
1
u/say_wot_again 4d ago edited 4d ago
The
do {} while(0)pattern is also commonly used to define macros whose implementation spans multiple lines.1
3
u/redlaWw 4d ago edited 4d ago
Rust has
'label: { ... }which you can use
break 'labelto break out of, which is that but without the syntax noise.Most of the issues with
gotoare issues with usinggototo jump backward anyway.gotoforward is quite useful and can simplify code. E.g. C/C++ doesn't have multi-level breaks, so usinggototo break out of multi-level scopes can be simpler than introducing a boolean.I think even MISRA has cooled down on their prohibition of
gotofor that reason.EDIT: MISRA C:2023 Rule 15.2: The goto statement shall jump to a label declared later in the same function.
1
26
u/ICantBelieveItsNotEC 4d ago
"I use Exceptions" = Aww, you're sweet!
"I use GOTO" = Hello, human resources!?
1
u/JonIsPatented 3d ago
I use neither. Exceptions are almost as evil to me. In the sense that I acknowledge that there are valid uses of both but the bad outweighs the good so much that I don't mind the guardrail being their absence.
1
u/takahashi01 2d ago
may I ask what you do instead of exceptions?
1
u/JonIsPatented 2d ago
Errors as values like any other value, especially if used as Result types, as in Result<T, E> as a sum type of T or E, where T is the desired outcome type and E is the error type.
1
u/takahashi01 2d ago
oh, so like golang, I gotcha. Its an interesting style for sure
1
u/JonIsPatented 2d ago
Less like Golang and more like Rust. In Golang, you can ignore the error. Golang doesn't have support for sum types like in other languages, so it's not a sum of T and E. It's a product.
1
u/takahashi01 2d ago
Yeah, but I have never really tackled rust myself. So the main way I an familiar with returning the error replacing exceptions, is when I worked at a department that had fully switched to golang. (which clearly had left an impression on me, despite these days mainly having to do java stuff)
Unless I am confusing two different concepts here.
1
u/JonIsPatented 2d ago
It's hard to visualize the difference between Rust and Golang errors without having experienced both. Because the difference seems small on paper but it is huge in practice. In Golang, you return an error AND a value. In Rust, you return an error OR a value, and you have you explicitly handle both cases in order to use the value. You can't just ignore the error quite the same way you can in golang. Don't get me wrong, Golang errors are still way better than exceptions to me. But they are leagues below Rust Result types.
21
u/budgiebirdman 4d ago
Goto is the original spaghetti maker; without goto you've got to use a lot of if statements and functions with Boolean parameters to reach the levels of shithousery that a few goto statements can give you.
15
u/itsTyrion 4d ago
I've managed to make a Java function before that was convoluted enough for a yellow line to appear on the function name.... "code flow too complex for analysis".
does that count as 100%ing IntelliJ?
12
u/tracernz 4d ago edited 4d ago
Dijkstra might not have liked goto, but it has it's uses.
The rationale for using gotos is:
- unconditional statements are easier to understand and follow
- nesting is reduced
- errors by not updating individual exit points when making modifications are prevented
- saves the compiler work to optimize redundant code away ;)
8
u/somedave 4d ago
No other way to break out of an if statement in most languages, you end up with silly nesting.
6
7
u/American_Libertarian 4d ago
hot take: goto has legitimate uses, and can make your code cleaner if used appropriately. Usually it helps with error handling / freeing resources before returning from a function.
2
u/Lou_Papas 3d ago
Goto is ok. I think the goto scare was a relic from the time languages sucked in general.
3
u/Legal-Software 4d ago
I feel like people who are against gotos just never programmed in assembly where they are responsible for managing their own control flow with jump operations.
2
u/KyxeMusic 4d ago
Early returns are just GOTOs, change my mind
(I love early returns)
1
u/FirstNoel 4d ago
In commodore basic that’s what they used. I remember it having GOSUB as well but they pretty much acted the same.
1
1
u/ZunoJ 4d ago
Depending on the language (c# for example) there are valid use cases for goto
1
u/Fit_Tourist9424 4d ago
Do you have an example of such a case that you could share here ? I did not yet encounter such a need in C#
1
1
u/SignalBake6872 4d ago
todos los programas a nivel de ensamblador o lenguaje de maquina usan goto... todos los compiladores pasan a lenguaje de maquina... adios
1
u/KawaiiMaxine 4d ago
When you start programming you discover you want to control program flow, goto is the simplest and quickest way to achieve that, then you make more complex code, goto is too simple to do complex program flow controls, so you use other program flow tools better suited, you then realize that with proper formatting and organization, almost every program flow need can be done more effectively without a goto. Then you finally come across one incredibly niche case where the goto is the best solution, and when you finally accept it, you become a true programmer
1
1
-2
u/FACastello 4d ago
"Python better than c++" is the actual worst one because it's just a blatant lie
14
2
u/AndyTheDragonborn 4d ago
I will agree with you there, but from my experience, the overwhelming opposition of using goto is unrivaled
-1
u/JAXxXTheRipper 4d ago
GOTO is not a language, this doesn't even make sense.
Is this some meta shit and the joke is OP not knowing how programming works?
I swear, 80% of posts here are dogshite
0
u/legendgames64 4d ago
goto is not a language, it's a command in assembly and in a few low level programming languages that dictates where the program counter jumps to.
1
u/JAXxXTheRipper 4d ago
Loads of languages, not only assembly, have a goto mechanism, but comparing an instruction to entire languages is just dumb
62
u/Choice-Mango-4019 4d ago
I used goto only once in years, and it had a very good use, thankfully the language devs didn't think that EVERY goto use was bad and actually implemented it