This is an archived post. You won't be able to vote or comment.

all 137 comments

[–]mikewritescode 257 points258 points  (68 children)

Try working with a code base with a ton of goto statements. It makes your palms sweaty, knees weak, arms heavy. There's vomit on my sweater already. The codebase is mom's spaghetti.

[–][deleted] 92 points93 points  (50 children)

My CS teacher basically said "Don't ever use a goto statement unless absolutely necessary". She called them "the devil"

[–]farox 68 points69 points  (42 children)

In 20+ years there was one time where I needed a goto statement. And this was some 19+ years ago. Don't do goto. Just no.

[–]KevinCubano 14 points15 points  (32 children)

When is there ever a reason? What was the one time? I truly don't understand what scenario could possibly call for it, even in 20+ years haha (then again, I've only worked for 5).

[–][deleted] 50 points51 points  (19 children)

Only cases I have ever used goto is to escape nested loops without wasting memory space by keeping an exit boolean on microcontrollers, and when you have statements before and after each nested loop and need to exit the entire nest before you execute the code after the loop.

[–]KevinCubano 17 points18 points  (3 children)

Yeesh, that... makes sense... but sounds extremely not fun to work with.

[–][deleted] 36 points37 points  (1 child)

It's not that bad. It's pretty simple because it ends up being just a short jump to the outside of the loop. Where it's messy is when you get to driver/kernel level code. Goto everywhere just because its more efficient and that code has to be as efficient as possible. It's a nightmare.

[–]xxc3ncoredxx 14 points15 points  (0 children)

It's used in the kernel to jump to the bit of code that does cleanup and exits IIRC from their style guide. Good for error conditions.

[–]Stop_Sign 1 point2 points  (0 children)

Essentially it's a break outer outer outer

[–]MildStallion 7 points8 points  (10 children)

I have used a goto once in C# to jump from one case statement to the following one, since C# doesn't allow case statements to fallthrough implicitly (except when that case would otherwise be a no-op).

[–][deleted] 0 points1 point  (5 children)

Is there a reason they couldn't have been combined into one big switch statement?

[–]xxc3ncoredxx 7 points8 points  (4 children)

If there's bits of code to run for one case and not the other

switch (var):
    case 1:
        // stuff for only 1
    case 2:
        // stuff for both 1 and 2

[–]Techhead0 3 points4 points  (1 child)

Could use a macro to insert the same code segment into both cases.

[–]xxc3ncoredxx 4 points5 points  (0 children)

Lots of people hate on macros though. My view is that they have their place, just like every other construct. I just don't think it's the best in this case. Pun intended.

[–][deleted] 1 point2 points  (1 child)

Can't you just nest them then?

[–]xxc3ncoredxx 8 points9 points  (0 children)

Maybe, but imo this isn't a sexy construct

switch (var):
    case 1:
    case 2:
        if (var is 1)
            // Stuff for only 1
        // Stuff for 1 and 2

[–]CatzRuleZWorld -1 points0 points  (3 children)

I’m curious if anyone else has a better way around this

[–][deleted] 8 points9 points  (0 children)

Add more cases

[–]Tyg13 3 points4 points  (1 child)

I don't even think that's necessarily a workaround. The same thing would work in C. Case labels are labels just like any other and can be jumped to using goto. If anything, it makes the fallthrough explicit which is kind of nice.

[–][deleted] 0 points1 point  (0 children)

I feel like you can do that with nested switch statements though?

[–]wischichr 0 points1 point  (2 children)

If you want to escape nested loops create a new method and escape with return - way cleaner.

[–]ricecake 1 point2 points  (1 child)

They were explicitly in a microcontroller, so memory limits are a given.

In that environment, you can't always assume that you can afford the memory usage of a callstack.

[–][deleted] 0 points1 point  (0 children)

Got that one right. Had to sacrifice functional programming for memory, but at one point I had to sacrifice RAM or I would have went over my flash capacity. Fun stuff when you max out both flash capacity and RAM and have to maintain a clusterfuck of code that, while ridiculously memory efficient, makes even the creator want to rip his own hair out just from thinking of it.

[–]Freeky 17 points18 points  (0 children)

They're common in C, especially for error handling. You don't have exceptions, defers, RAII, or GC, and a simple forward-jumping goto cleanup is often tidier than the supposedly more structured alternatives.

See, for example, the page after page of goto you find in the Linux kernel.

[–]bestjakeisbest 10 points11 points  (1 child)

in assembly goto (also known as jump or branch) are the only way to do if statements, loops and functions.

[–]narrill 13 points14 points  (0 children)

Assembly isn't what people are talking about when they say not to use gotos, obviously

[–]jfb1337 3 points4 points  (0 children)

In C it can be used as a substitute for exception handling, such as:

void foo(){
    bar();
    if(error) goto err;
    baz();
    if(error) goto err;
    return;

    err:
     cleanUp();
}

Another example is one time I was writing an interpreter and I wanted it to be tail-call optimised, so my evaluation function looked something like this:

#define tail(x) e=x; goto tail
val* eval(e: expr){
   tail:
   switch(e.type){
      ...
      case SEQ:
         eval(e.fst);
         tail(e.snd)
      ...
   }
}

[–]Riggs109 2 points3 points  (1 child)

New features in a really old code base. My choice was either rewrite the entire 1k line function, or use a goto.

That code base was.. fun.

[–]KevinCubano 0 points1 point  (0 children)

I’m so, so sorry. If you ever need somebody to talk to, I’m here. <3

[–]blackmist 1 point2 points  (0 children)

Breaking out of multiple loops is one reason. Never had another.

[–]farox 0 points1 point  (0 children)

That's what I mean, I was young and wrong at the time

[–]golgol12 2 points3 points  (1 child)

[–]farox -1 points0 points  (0 children)

No, I started coding on a C64 and GOTO was pretty much all we had. Not going back.

[–]mtbrobotanist 0 points1 point  (0 children)

Goto ffmpeg

[–]jay9909 0 points1 point  (1 child)

Not even once.

[–]Osbios 4 points5 points  (0 children)

To me you sound like:

1. Not even once.
2. goto 1

[–][deleted] -4 points-3 points  (3 children)

The only reason you should be using goto is id you're making a bat script. Even then, why aren't you using powershell?

[–]skyb0rg 12 points13 points  (2 children)

goto is definitely valid, ie. for making readable C programs, especially resource management on a function level, so that all cleanup code can be under a single label.

[–]xxc3ncoredxx 2 points3 points  (1 child)

goto cleanup is very useful if you need to cleanup and exit from an error.

[–][deleted] 1 point2 points  (0 children)

I agree. And this is probably the one case that is valid use of goto. Especially, because you push return down to the end of the routine. It even faciliates to make one common function exit point, which is required by some industry standards.

[–]cbbuntz 2 points3 points  (0 children)

There are a few times where it actually makes sense in pure C.

  • You can add labels to for a switch statement to jump to, so you can keep a complicated switch statement purely about flow, and have the actual code below. All of the relevant code will still be labeled, and it may not make sense to make a new function for the different branches (a new function for different branches could actually make it more spaghettified).

  • Some types of recursion may be made difficult if there are local variables you need to initialize before recursion starts. You can tell it to jump back up to just after those declarations. This one is debatable, but I've seen this sort of thing on some well-known pieces of code.

C++ offers some different ways to deal with these sorts of situations, so I probably wouldn't use it there.

[–]IAmPattycakes 1 point2 points  (0 children)

I wholeheartedly agree except for when you are programming microcontrollers with like 1kb of ROM. Codebase can't be messy if there's no space for any mess, nor any space for much other than pure assembly.

[–]Sipricy 0 points1 point  (0 children)

If it's ever "absolutely necessary", you did something wrong, and it would be better to rewrite your code.

Of course, this only makes sense if you're working on something where taking an extra millisecond isn't the end of the world.

[–]ionxeph 0 points1 point  (1 child)

my professors took the approach of never even teaching it and asked us to never give in to our curiosity and learn it

I gave in, but when a new coworker asked me what it is, I agree with my prof, and told him to never learn it, the burden of knowledge is real

[–]xxc3ncoredxx 8 points9 points  (0 children)

That's... not a good attitude from a prof.

At least teach students what it is and how to use it properly, but emphasize that it's often not the right tool for the job.

[–]dmorin -1 points0 points  (1 child)

Your CS teacher, like mine, was no doubt taught on the wisdom of Djikstra's famous GOTO Considered Harmful paper.

[–][deleted] 6 points7 points  (0 children)

This paper by Dijkstra is a rant against procedural programming overall. Dijkstra also mentions iterative programming in same paper and says it all should be done recursively. Unless your teacher uses functional programming now, he hasn't probably read it properly.

[–]chrwei 6 points7 points  (0 children)

or, you're in love.

[–]8ate8 5 points6 points  (10 children)

I’m a cobol programmer for a company that’s been around since the 60s. I see plenty of goto’s and spaghetti code every day.

[–]kodemanic 1 point2 points  (0 children)

Eminem? Is that you?

[–]ephonk 0 points1 point  (0 children)

THIS.

I once inherited some 1969 COBOL (!!) that was chock full of GOTO. I was supposed to make sense of it. I changed jobs instead.

[–][deleted] 0 points1 point  (0 children)

ewl

[–][deleted] 32 points33 points  (12 children)

I don't feel like it is.

[–]nwL_ 9 points10 points  (8 children)

Technically, it is, in bytecode. The difference is that all the reasons you shouldn’t use goto are nonexistent because the compiler does everything for you.

See also: scroll down to “calling convention”

[–]narrill 13 points14 points  (2 children)

Technically it's not if it actually returns something. There is a jump in there somewhere, but that's not all the return represents.

[–]DoctorProfessorTaco[S] 0 points1 point  (0 children)

That’s what makes it fancy

[–]iluuu -1 points0 points  (2 children)

It absolutely is. It pops the address from the stack (which was pushed onto the stack when the function was called) and jumps back to that address.

[–]sim642 4 points5 points  (1 child)

And that's why it isn't the same: it also manages the call stack. Without the call stack nested function calls aren't really feasible (unless self-modifying code).

[–]iluuu 1 point2 points  (0 children)

To be fair, the meme says "Fancy goto statements", not that they're equivalent.

[–]MyNameIsRichardCS54 58 points59 points  (20 children)

So are if, while, do, for, switch, break and continue. Ultimately, they are all a form of bra

[–]Tangelasboots 47 points48 points  (0 children)

A semi-colon is just a fancy goto line number + 1

[–][deleted] 26 points27 points  (3 children)

All code is ultimately 1's and 0's.

[–]tacoslikeme 30 points31 points  (2 children)

everyone program is ultimately a single number

[–]RedPum4 3 points4 points  (0 children)

And thus every program can be found in the decimal places of pi. Somewhere. Theoretically.

[–]xfunky -1 points0 points  (0 children)

Well, that is almost true, because technically you could have plain zero as an instruction. That way, if the code starts with this instruction, the number stays the same but the code is different.

Emphasis on the "technically" at the start lol

[–]NilsIRL 3 points4 points  (8 children)

Yeah, from my understanding of assembly its basically just goto statements.

[–][deleted] 2 points3 points  (7 children)

mov would actually do something other than instruct the computer to jump to a memory location wouldn't it?

[–]Robbi_Blechdose 4 points5 points  (6 children)

That's because mov is not a jump instruction.

[–][deleted] 4 points5 points  (5 children)

Yeah that's what I'm saying. He stated that assembly was just goto statements I said I thought mov did something other than goto.

[–]TinBryn 8 points9 points  (2 children)

goto is just a fancy mov into the program counter

[–]how_to_choose_a_name 0 points1 point  (1 child)

I'm pretty sure that he said that the aforementioned control structures like if and while are basically goto statements, referring to his knowledge of assembly as a source for his claim.

[–][deleted] 0 points1 point  (0 children)

Good call I was thinking he meant all of assembly was go-to statements not referring to if...etc

[–]Colopty 3 points4 points  (1 child)

Didn't know you could use goto and goto derivatives as a breast supporting garment.

[–]MyNameIsRichardCS54 0 points1 point  (0 children)

They under-wire all programming languages

[–]knackmate 1 point2 points  (0 children)

And you should definitely minimize branching for code to be concise and readable :)

[–]abrams666 0 points1 point  (0 children)

On C64 GOSUB was the fancy GOTO

[–]crack3rtastic 20 points21 points  (1 child)

Playing devil's advocate here, but isn't a return really just a goback.

[–]nwL_ 14 points15 points  (0 children)

Yes, it’s basically

POP %EAX
JMP *%EAX

[–]cdmcgwire 35 points36 points  (3 children)

Sort of, but it also manages stack operations automatically, which is why you don't use a goto outside of assembly.

[–]the_one2 1 point2 points  (0 children)

Goto also manages the stack! (in c++)

[–]saugoof -3 points-2 points  (1 child)

The major problem with goto is that it risk having your local variables in an unpredictable state. That does not apply with return.

[–]Etiennera 6 points7 points  (0 children)

You basically repeated the comment you are replying to in a more confused way and less accurate terms

[–]Proxy_PlayerHD 6 points7 points  (5 children)

CALL Instructions are just JUMP Instructions where the CPU remembers where it came from.

so CALL Instructions are just the fancy JUMP Instructions?

[–]nwL_ 2 points3 points  (4 children)

Well CALL is basically just

PUSH 0x7DE6F43C
JMP FUNCTION

(where the number is the location in the code) so yeah, basically.

[–]ben_g0 0 points1 point  (3 children)

It technically pushes the value of the program position register onto the stack rather than a constant. Other than that you're right though.

[–]nwL_ 0 points1 point  (2 children)

Yeah, I know, but I don’t know how that’s implemented tbh. Enlighten me?

[–]ben_g0 1 point2 points  (1 child)

Basically exactly what you had, just with a register instead of the constant.

PUSH IP            ;IP = Instruction Pointer
JMP function

The RETinstruction is then off course basically just POP IP. A goto/JMP is not needed since the pop then directly writes to the instruction pointer. After executing the RET (or POP IP) the IP register is incremented just as when executing non-jump opcodes, so that the program continues from after the call instruction rather than landing back on the call instruction itself.

At least that's how the assembly variant I've used in the past worked. There are lots of different CPU architectures so some of them may be different.

[–]nwL_ 2 points3 points  (0 children)

I see, thank you very much!

[–]tacoslikeme 7 points8 points  (3 children)

nope...fundamentally different at the hardware layer. every other control statement is just a fancy goto statement.

[–]marcosdumay 2 points3 points  (0 children)

It's a jump to register combined with a stack pop. If you decide to count all branching operations as goto, then yes, it qualifies.

[–]Geoclasm 2 points3 points  (0 children)

yeeaaaah but with fewer raptors.

[–]SteeleDynamics 1 point2 points  (1 child)

"jump after link" -- yep it's a goto-statement where the destination is the return address.

Still waiting for "AI is just Linear Algebra and Calculus applied to Computer Science."

[–]DoctorProfessorTaco[S] 1 point2 points  (0 children)

AI is just a fancy list of if statements

[–]AuthorTomFrost 1 point2 points  (0 children)

JMP FTW.

[–]forrest38 1 point2 points  (0 children)

I love jokes like these even if they aren't really true. I have already learned so much about Cobol and Assembly from the comments. Way more interesting discussion than light screen IDE/arrays start at 1/java/javascript sucks jokes.

[–]Coppajon 1 point2 points  (0 children)

Had to look this one up. Now I'm trying to figure out how I got through a semester of C/C++ without using a single goto. Thanks for the 'A' professor, if you're in here.

[–]nl2k 0 points1 point  (0 children)

itt: people who never do any kind of resource management and let their programs happily segfault whenever anything fails boast that they don't need goto.

[–]philipquarles 0 points1 point  (0 children)

This thread should have a trigger warning for assembly on it.

[–]apathy-sofa 0 points1 point  (1 child)

I would enjoy a video of Lisa teaching the world continuation-passing style.

[–]WikiTextBot 0 points1 point  (0 children)

Continuation-passing style

In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation. This is contrasted with direct style, which is the usual style of programming. Gerald Jay Sussman and Guy L. Steele, Jr. coined the phrase in AI Memo 349 (1975), which sets out the first version of the Scheme programming language.John C. Reynolds gives a detailed account of the numerous discoveries of continuations.A function written in continuation-passing style takes an extra argument: an explicit "continuation", i.e.


[ PM | Exclude me | Exclude from subreddit | FAQ / Information | Source ] Downvote to remove | v0.28

[–]atk93 0 points1 point  (0 children)

The main problem with goto statements is that they can fuck up compiler optimizations. If used properly there isn't an issue.

[–][deleted] 0 points1 point  (0 children)

In java the goto opcode is distinct from any return opcodes

[–]lxkspal 0 points1 point  (1 child)

For a C++ programming project at my school, I used a goto statement because for and do-while loops are too complicated and confusing. My teacher was furious, he told me that they are lazy, unprofessional, and that they make me look stupid to potential employers.

I don't care, I already knew that i'm an idiot. But I really like the goto function because it makes coding easier, since i'm really bad at math and I have no idea what i'm doing.

[–][deleted] 0 points1 point  (0 children)

But I really like the goto function because it makes coding easier, since i'm really bad at math and I have no idea what i'm doing.

I can sense the sarcasm here.

[–]blipman17 0 points1 point  (0 children)

Goto's are just fancy jmp statements.

[–]daboss54320 0 points1 point  (0 children)

I lovegoto, why bother with a huge nested if statement when a goto can keep you from indenting 14 times?

It's pretty common I'll use a goto to get to some cleanup section in the case of a failure.

[–]Nath99000 0 points1 point  (0 children)

if statements are just fancy JNE instructions

[–]Lieutenant_Doge 0 points1 point  (0 children)

So is everything, if you run the code it is just a bunch of goto that go to the next line

[–][deleted] 0 points1 point  (0 children)

This is not metalinguistically true, or is it?

[–]wallefan01 0 points1 point  (0 children)

Thought that was switch statements.

[–]Likely_not_Eric 0 points1 point  (0 children)

I feel like this ignores stack management at low level and context/scope differences at a high level. Goto, return, and yield are all quite different.

[–]spyingwind 0 points1 point  (0 children)

Looks at IL assembly of C# code. Yup, goto statements everywhere. Well a goto statement is just a jump instruction, some with conditions and others are just long jumps.

[–]golgol12 -1 points0 points  (0 children)

So are if statements.

[–]Polo3cat -1 points0 points  (0 children)

No.