Goto

what are some scenarios where using


goto label;
..
.
label: statement;

is legitimately the best solution?

Other urls found in this thread:

blog.rust-lang.org/2016/04/19/MIR.html
twitter.com/AnonBabble

never

programming in basic

also what was the worst goto abuse you have ever encountered?

scenario 1) you know what the fuck you are doing
scenario 2) you want to cause the most immense butthurt in pleb tier brogrammers possible

Most of the time, when you want to get fired.

Error handling in C, where you don't have exceptions

The only reasonable use I've found too

this.

tho the only place i've seen it used is in embedded systems and infinite loops.

To jump the fuck out of nested loops

in this case, using functions is usually the better soultion

I'm curious if anyone has seen any crazy use of C's setjmp.h functionality.....

For some odd reason, libpng uses it in its public interface.
But otherwise, I've never seen a good use of it.

care to explain how a function call is superior to an unconditional jump?

If you prefer not to use GOTOs, something like

while (expression) {
while (expression) {
if (something)
goto dblbreak;
/* more code here */
}
}


can be implemented like

int innerloop(...) {
while (expression) {
if (something)
return 1; // preferabally a symbolic constant
/* more code here */
}
return 0;
}

/* main loop */
while (expression) {
if (innerloop(...))
break;
}


Obviously, which is better is going to depend on your application. But I tend to see this as an alternative to GOTO.

the label "dblbreak" should come after the outer-loop in the first snippet. forgot that, oops

in such a case you're still using an unconditional jump, the only difference being that the goto and break lead to the same program counter
but what if you want the program counter to be something different? say before the outer loop or between or really anywhere that isn't where a break or continue would lead you?

not trying to bust your balls or anything, but i feel it's not perhaps the best example

perhaps not. I will say I wasn't approaching it from a performance standpoint, just a maintainability one. Since, as well as cleaning out a goto statement, writing the loop in a separate function make the calling function more human-readable (usually).

readability and maintenance are both fair points
also the performance issue is a thing since i happen to believe that your compiler will throw the function call in the garbage and still nest the loops as they are in the first snippet to reduce the function call overhead
it might even unroll the loops or god knows what black magic

Why is goto hated so much?

I've never used it, though I've considered using it given the fact that it is an extremely simple and convenient way of breaking out of a nested loop.

However every book/article that introduces or explains goto says immediately after "but don't you dare actually use goto, though". I've never read an explanation as to why people shouldn't use it, nor why it was invented, still taught and still a feature in many languages if "there's always a better way to solve the problem" (which is never explained either).

because in large codebases beyond the size of a homework problem it leads to messy, inflexible code

same reason as pointers i reckon. if you can avoid using them then you probably should. BUT! if you know your shit then by all means sprinkle them about liberally

When you have multiple control paths converging within a function.

No, actually you should use the break statement in this case. It's specifically intended for local control transfer out of a loop.

That's awkward if the inner loop must access or modify variables in the main loops's scope. You end up having to package a bunch of variables in a struct and pass a pointer to the struct when calling innerloop(). Also, since C doesn't support nested functions, naming becomes awkward if you have multiple functions containing inner loops.

Main drawback of GOTO is that it makes program flow difficult to understand, look up some old line-numbered BASIC or FORTRAN sources and see how much harder they are to make sense of than something structured like C or Java. Pretty much ALL control flow statements are implemented as gotos anyway, but they have restrictions which make them easier to understand and harder to fuck up.

Though with named rather than numbered labels, GOTO-heavy code is easier to understand today, "goto drawmap" is a lot more meaningful than "goto 400".

>No, actually you should use the break statement in this case. It's specifically intended for local control transfer out of a loop.
the keyword here is 'a' loop, not all of them, but only one. if the intent is to jump further than an inner loop then goto is the way to goto

>Main drawback of GOTO is that it makes program flow difficult to understand
this i agree wholeheartedly, but not from the human perspective. it's actually very easy to follow goto statements with labels (and even hex or whatever you use for the program counter). it's not so easy for the machine to do branch prediction apparently. but since i only deal with really low level close to the iron stuff this hasn't been an issue for me. i can still sympathize with higher level folk who piss on goto for that very reason

>You end up having to package a bunch of variables in a struct and pass a pointer to the struct when calling innerloop().
you can also just pass them by reference on their own. no need to struct them up

Goto is usually the cleanest solution if you have a programming language that does not support breaking to a named outer loop.

Example:

bool found = false;
for (unsigned x = 0; x < width; x++)
for (unsigned y = 0; y < height; y++)
if (a[x][y] == target) { found = true; goto done; }
done: ;


You can do this by including "&& !found" in the test, but to my eye, goto is a little simpler and cleaner.

I think that accounts for about 90% of all the times I've used goto in my whole career.

I also find myself writing parsers for various little languages, like command interpreters and so forth. Over the years, I've noticed that there are some rare situations where it's just quicker to use a goto -- it usually ends up eliminating an if, while, or boolean, and it prevents me from having to twist things around unnaturally, or duplicate any code. I believe in every case, the goto is either "goto end;" or "goto start;" and I have always found it really easy to follow the code.

judging by the control flow here the bool found is unnecessary and will be optimized out

because it makes the control flow harder to understand

when you use if, for, while, etc they define a scope both semantically and visually (inside the curly braces) and it's easy to reason what parts of the code will be executed when and how many times

when you use gotos you have to manually search for the target label and reason how does it reach that goto and what happens when it jumps to that label
you could jump out of control structures, into them, you can create loops, you can skip over initializations or frees or over return statements. goto is this tool in C that just says "fuck you" to everything, much like pointers and the "mutable" type qualifier in C++. C/C++ has this way of providing you with a sane, reasonable way of doing things but also a few low-level tools that you can use to do and break anything

gotos are avoided because it's easy to write spaghetti code if you rely too much on them

goto label;
..
.
label: statement;

>what are some scenarios where using

1986.

>scenario 1) you know what the fuck you are doing

if you knew what you are doing, you wouldn't even think about using goto

>judging by the control flow here the bool found is unnecessary and will be optimized out

Typically, after the code I posted, you would do a "if (found)...", or maybe a "return found;".

You are correct that if the code I posted was the only code, then the "found" would probably be optimized out. However, there's no point in setting a "found" boolean if you don't use it later. Once you use it, the compiler will not optimize it out. In the ideal world, no programmer would be stupid enough to write all that code to set a "found" variable and then neglect to use the result of the search.

Nested loops and error handling in C.

for (i = 0; i < n; ++i) {
for (j = i; j < m; j += t) {
for (k = i + j; k >= l; k -= n) {
if (some_condition) goto loop_break; // rather than passing i, j, k, l, m, n and some_condition to another function
}
}
}
loop_break:


another one

if ((ptr1 = malloc(some_size)) == NULL) {
ret = ENOMEM;
goto exit;
}

if ((ptr2 = malloc(some_other_size)) == NULL) {
ret = ENOMEM;
goto free_ptr1;
}

if ((ret = pthread_mutex_lock(&lock)) != 0) {
goto free_ptr2;
}

if ((ret = some_function()) != 0) {
goto release_lock;
}

do_stuff();

release_lock:
pthread_mutex_unlock(&lock);

free_ptr2:
free(ptr2);

free_ptr1:
free(ptr1);

exit:
return ret;

>because it makes the control flow harder to understand

I used to teach computer science at the college level. This is what I always told my students in the introductory course about goto:

You can use goto if you can make a compelling case that there is no cleaner or more obvious way to write the code using if, for, while, do, etc. Every time you use goto, you MUST first search for an equally clean (or cleaner) way to rewrite the code without goto, and your search MUST fail, and your search MUST be thorough enough to convince most skilled programmers that you considered all reasonable alternatives.

>if (found)
a conditional branch, defeating the whole point of an unconditional branch
>or maybe a "return found;
a simple return would suffice then, no?
>However, there's no point in setting a "found" boolean if you don't use it later.
and you didn't...
>Once you use it, the compiler will not optimize it out.
unless the usage itself is meaningless to the machine
>In the ideal world, no programmer would be stupid enough
but we are all stupid regardless of what we tell ourselves or other people

anyway, there's a way out of your posted loop structure by simplifying it from a nested two dimensional loop to a one dimensional loop. then only a simple break statement on element found would do the trick without even needing to consider gotos or other trickery

They are great for writing algorithms that run smoothly on asymmetrical hardware. Higher-level control structures might lead to graphical glitches and overall failure on machines like these.

This is obviously fine if you don't need to capture/pass too much state and if your compiler supports inlining.

If you need to capture state and you're using C++11 or newer, you can use a lambda for innerloop. But I would be weary of what optimisations the compiler is able to do if this is a tight loop.

I've seen it used in some C code to catch stack overflows and expand the stack instead of segfaulting

I've seen it quite commonly used for emulating C++ style exceptions

jmp_buf je;

void catch(int e) {
longjmp(je, e);
}

void foo() {
int e;
int* ptr = NULL;
float a, b;

signal(SIGFPE, catch);
signal(SIGSEGV, catch);

if ((e = setjmp(je)) == 0) { /* try */
b = 2.0; --b; --b;
a = 1.0 / b; // division by zero
}
else if (e == SIGFPE) { /* catch SIGFPE */
*ptr = 0xdeadbeef;
}
else if (e == SIGSEGV) { /* catch SIGSEGV */
}

}

When you want to bypass some code during testing and the easiest thing is to just wrap it with a quick GOTO and label.

goto newCode
//old code is here
newCode:

>When you want to bypass some code during testing and the easiest thing is to just wrap it with a quick GOTO and label.
I disagree, wrapping it in a block comment is a lot better because it suppresses any compiler warnings.

the easiest thing is to just
/*

...

*/

>block comment
yeah, if the lang supports it

What C syntax language does not support block commenting?

What editor or IDE does not support commenting out entire blocks using single line comments?

regardless of language your development environment should have a hotkey to comment/uncomment blocks of code

i mean, you are using an IDE aren't you? you're not one of "those" CLI retards are you?

>i mean, you are using an IDE aren't you? you're not one of "those" CLI retards are you?
Even if you use Emacs or vi or even freaking nano, those still support selecting multiple lines and commenting out a block.

not sure about nano tho

nvm, it's even possible in nano

This is the only use I find acceptable. Its not breaking existing rules, changing flow control unexpectedly or over complicated. All it is doing is avoiding if statement indentation.

This format is pretty common in file operations, where you progressively acquire resources to do work then need to clean up after yourself. But it should remain a higher level function like where do_stuff() does the actual work.

>All it is doing is avoiding if statement indentation.
wut? no!
it reduces instruction count. you could achieve the same program flow with no additional indentation by freeing progressively with each failed allocation.
>But it should remain a higher level function like where do_stuff() does the actual work.
absolutely a matter of taste. if you follow the ideology of writing small functions for everything then ok, fine. but in reality all the heavy lifting could just as easily be done in the same scope.

example 1:
{
if (error)
goto cleanup;

doSomething();

if (anotherError)
goto cleanup;

return success;

cleanup:
undoSomeShit();
return failure;
}


example 2:
{
for (item i in collection) {
if (item meets criteria A)
goto found;

calculation();

if (item meets criteria B)
goto found;
}

return error;

found:
// rest of the function

return result;
}


example 3:
{
if (some_condition) {
trySomething();
if (it worked)
goto done;
}

if (some_other_condition)
goto done;

processSomething();
if (third condition)
goto done;

return nothing_worked;

done:
// rest of the function

return result;
}

Batch files (.bat , .cmd)

You absolutely need it in C++ if you use exceptions and need to deallocate memory (without having to repeat the same code section twice). C++ doesn't have a "finally" like Java. Am I wrong?

>deallocate memory
Use a smart pointer

>C++ doesn't have a "finally" like Java. Am I wrong?
try {
// ...
} catch (...) {
}
// what's wrong with putting code here

usually, a finally section is in the same scope as the corresponding try and catch blocks. (it IS a sub-scope of the function it exists in).

Though personally, I like to declare all my local vars at the top of a function, so this wouldn't matter in this case.

It's been a while since I worked with C++. I remember that auto pointers were shit and support for smart pointers was even across compilers. Has that changed?

Using a struct is more efficient since you can pass it with only one pointer, so the stack frame can be smaller. It's not that you can't pass them individually, but if you have to pass a bunch of state around, putting it in a struct makes it easier.

Yes, C++ smart pointers (shared_ptr, unique_ptr) are great in C++ (C++11, C++14, etc.) you should never write a non-empty destructor unless you have a VERY good reason to be manually managing memory.

>Use a smart pointer
C++ programmers will defend this

>imblying that memory allocation is the only form of resource allocation.

And you can have all of your other resources managed automatically, too. std::*stream's close the pipe in their destructors; I'm sure any respectable networking library does the same

>Why is goto hated so much?

GOTO in and of itself isn't hated. Abusing GOTO rather than calling functions is hated.

Other uses of GOTO is merely distasteful.

The only time you should be writing GOTO is if you're writing extremely performance-critical code. And not, "oh, I think this will be important once we hit X users", I mean, "oh shit my manager is breathing down my neck about the performance of this functionality that is core to our business".

Examples of places where GOTO might be reasonably used: network stacks and image-processing libraries.

>I'm sure any respectable networking library

Yeah, let's No-True-Scotsman up in this bitch rather than acknowledging the dirty reality of software engineering.

goto bed;
..
.
bed: sleep;

I can't imagine it being very hard to close the socket in the destructor...
What's your argument, anyways? That we shouldn't take advantage of RAII?

when you've coded yourself into a corner and the sprint is over at EOD and you've gotta deliver to QA NOW so you don't look stupid on the morning call.

When you're maintaining legacy code that uses it.

>What's your argument, anyways?

That this claim is naive and wrong:

> > you should never write a non-empty destructor unless you have a VERY good reason to be manually managing memory.

>That we shouldn't take advantage of RAII?

You completely invented that. I don't know if you're ESL, or stupid, or what.

I don't know about C, but in most assembly languages when you use jump/goto/branch/whatever instructions there's a lot less overhead than calling a subroutine. On some older CPUs you pretty much want to avoid subroutine calls as much as possible for performance reasons, especially in loops.

Of course, on a modern computer you're talking an irrelevant amount of overhead unless you're doing something fucking retarded in the first place.

To me, "taking advantage of RAII" means letting C++ generate destructor cleanup code for you. Also, writing your own socket API would definitely be a "VERY" good reason to write a non-trivial destructor

>To me, "taking advantage of RAII" means letting C++ generate destructor cleanup code for you.

WTF. C++ automatic destructors aren't RAII. They're separate concepts, one of which *may* take advantage of the other.

>Also, writing your own socket API would definitely be a "VERY" good reason to write a non-trivial destructor

No clue why you're so obsessed with a socket API.

>putting conditional branch in a double loop
>Obviously better
I guarantee, if you do not use the goto, the code will run 10x slower.

Anyone who is still confused about why goto is a bad idea in most circumstances, I suggest you read Dijkstra's article "Go To Statement Considered Harmful"
surely the compiler can optimise it to a single JMP, making it the same as having the goto but without the extra label needed at the end of the loop.

>I don't know about C, but in most assembly languages when you use jump/goto/branch/whatever instructions there's a lot less overhead than calling a subroutine. On some older CPUs you pretty much want to avoid subroutine calls as much as possible for performance reasons, especially in loops.
Well
the overhead for a subroutine call generally isn't too much
what is generallydone is (and it's different for each system but whatever)

args for the subroutine are pushed onto the stack
space is made on the stack for things within the scope of the subroutine
space is made on the stack for the return value of the subroutine
the next address of the next instruction is pushed onto the stack

so like, not a lot of magic is done. in x86 and x86_64 sometimes they'll just use the registers instead of pushing everything onto the stack, like I said it depends on the compiler and the CPU and the compiler flags -- but at the end of the day there isn't a huuuuge load of magic going on with evoking a sub routine.

>surely the compiler can optimise it to a single JMP
sure, you just need to change the language to use named loops.
while (cond1)
while (cond2)
break cond1;

NAMED LOOPS
A
M
E
D

L
O
O
P
S

Use #1: When you have nested loops and don't want to use break for every single one.

Use #2: When a function has multiple exit points and needs some sort of cleanup or finish, easier to use multiple goto's to one cleanup label

There are more, but those seem to be the most common uses.

I think maybe when you want to build suspense or train the user.

>smart ptrs
Just use C# if you 're gunna be doing that.

First one to talk gets to goto my_aircraft;
[grabs a goto statement]
Who paid you to use goto?
[no answer, the agent fires his void pointed at his leg]
He didn't goto fly: return success;
[goto back_into_plane(the_hood);]
Who wants to try{goto next;}?
[grabs a C++ prisoner]
Tell me about Error handling! Why does it wear the curly braces? A lot of catches, for such a small try block !
BEN: Or perhaps he's wondering why someone would use conditional statements, before goto out_of_plane(him);?
At least you can code. *whoami's in your shell*
BEN: It doesn't matter whoami, what matters is structured programming.
[the Agent removes the goto]
BEN: No one cared who whoami until I showed your gf how to use compiler flags.
Agent: If I disable them, would it compile?
BEN: It would be extremely unoptimized.
Agent: You're a big O!
BEN: for (;you;);
Agent: Was using goto part of your design spec?
BEN: Of course... client refused our goto in favor of nested loops and cases, we had to find out what he was smoking.
Client: /dev/null! I told them void

>he thinks sepples is C with classes

if you need to break out of nested loops you are doing something wrong

is this bait?

nah, probably just a shitty java programmer who views code in fullscreen on a 16:9 monitor and think 200 columns of indentation are fine

My professor in uni told me to never ever use break.
That I should instead use a extra variable if I want to jump out of a loop early.

But I use break in loops when I'm searching a value because it's so easy to type, readable and I don't need another variable.

I also use the ternary if operator a lot because I like how it compresses 3 or 5 lines into one and I don't like the indenting the if command forces.

My professor in uni never told me about the ternary if operator.

Are these bad practises?

you're using the possibilities the language provides the way they are meant to be used

>My professor in uni told me to never ever use break.
get a refund and move to a country with a real education system

c network programming, there's many cases when a goto is the cleanest solution.
Also sometimes I prefer tu put a goto instead of a cycle to spare an indentation level, but that's me.

Because you have to know how to use it.
Putting only two goto to two different labels leads to unreadable code, and that's an easy mistake to do as a beginner given the power of the statement.

My way of thinking with goto statements is if you have to ask yourself if using goto is a good idea it probably isn't a good idea.

rust compiles everything to gotos in mir to do its borrowchecking and optimiziations

blog.rust-lang.org/2016/04/19/MIR.html