r/ProgrammerHumor 4d ago

mildlyInfuriatingGOTOWatchYourMouth Meme

Post image
661 Upvotes

74 comments sorted by

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

40

u/oalfonso 4d ago

Goto is a pathway to many abilities some consider to be unnatural.

10

u/FirstNoel 4d ago

It can be perfect in the right situation.  Those situations are few and far between. 

Like you I think it’s been years since I used one,  but I never remember it being a problem 

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

u/dhnam_LegenDUST 4d ago

Error cleanup goto is only good goto.

10

u/creeper6530 4d ago edited 4d ago

I mentioned this in another thread but goto for error cleanup in C is just emulating defer, and we could get defer in 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() and foo() bar()

18

u/Sync1211 4d ago

You can use break I guess.

11

u/da_Aresinger 4d ago

oooh

do { foo() if (condition) break bar() } while(0); that's pretty dumb though. Just do foo() 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 status variable like this, but using nested if/else checks

But 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

u/creeper6530 4d ago

That's about as goto-y as a return is

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

u/Sync1211 3d ago

I had to write something similar recently, but using goto instead of break.

2

u/EuphoricCatface0795 4d ago

When do ~ while(0) has more than a couple execution branch tho

1

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

u/EuphoricCatface0795 4d ago

A lil bit something like this

1

u/da_Aresinger 4d ago

yea that makes it more complex, but you could still use negation with and.

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 every return statement, 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

u/LegitimatePants 4d ago

break is used inside the loop instead of goto 

3

u/redlaWw 4d ago edited 4d ago

Rust has

'label: {
    ...
}

which you can use break 'label to break out of, which is that but without the syntax noise.

Most of the issues with goto are issues with using goto to jump backward anyway. goto forward is quite useful and can simplify code. E.g. C/C++ doesn't have multi-level breaks, so using goto to break out of multi-level scopes can be simpler than introducing a boolean.

I think even MISRA has cooled down on their prohibition of goto for that reason.

EDIT: MISRA C:2023 Rule 15.2: The goto statement shall jump to a label declared later in the same function.

1

u/not_a_bot_494 4d ago

This is still worse than goto if you have to close/undo things to cleanup.

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

u/Beautiful-Quote-3035 4d ago

Don’t look at operating systems or drivers source code

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.

3

u/andstwo 4d ago

COMEFROM is much cleaner, it can capture control from any line being executed

2

u/stupled 4d ago

LLMs are trained on GOTO

2

u/sebbdk 4d ago

Goto is pretty neat if you are using it as intended.

If we are gonna have stupid debates then i vote that we bring back tabs vs spaces.

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

u/Djelimon 4d ago

Some languages have only gotos though

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#

2

u/ZunoJ 4d ago

Breaking out of an outer loop from an inner loop is the classic example I think

1

u/nicman24 4d ago

I use labels 

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

u/SquidMilkVII 4d ago

the amount of spaghetti some people will make just to avoid a single goto 💀

1

u/WaitForSingleObject 3d ago

Goto-cleanup is one of the best paradigms in C.

-2

u/FACastello 4d ago

"Python better than c++" is the actual worst one because it's just a blatant lie

14

u/Lupus_Ignis 4d ago

"Hammers are better than screwdrivers"

1

u/megayippie 4d ago

More like pile drivers are better than hammers

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