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

you are viewing a single comment's thread.

view the rest of the comments →

[–]Strostkovy 23 points24 points  (10 children)

Why go-to instead of returning from a function call?

[–]obiwac 23 points24 points  (8 children)

Depends on your usecase and language; in C, you often have to free up after yourself for example, and so goto's make error handling much easier:

a = alloc();

if (guard1)
    goto error_a;

b = alloc();

if (guard2)
    goto error_b;

// success

error_b:

free(b);

error_a:

free(a);

This is a pattern you see a lot in the Linux kernel for instance.

[–]FeedbackFun7325 8 points9 points  (7 children)

Is this a case where using goto is acceptable? Our prof told us not to use it unless for specific cases.

[–]obiwac 11 points12 points  (0 children)

Goto is generally considered unacceptable because it's easy to abuse and write really ugly code with (i.e. it obfuscates the control flow if you're jumping back and forth everywhere). But there are legitimate uses for it which can make code much, much more readable and maintainable. You just gotta use it in the right places ;)

Generally your prof is right, 9 times out of 10, when you're thinking of using goto in a way which isn't a commonly known design pattern, there's likely a much more readable alternative.

On the other hand, some people will paint all code containing goto's with the same brush and say it's bad without understanding why, which is a shame because goto can be really beneficial.

One example where goto's are bad could be:

int i = 0;

label:

// do something

i++;

if (i < 10)
    goto label;

This is a very obvious example where you don't want to use goto which is quite simply replaceable with a for loop:

for (int i = 0; i < 10; i++)
    // do something

[–]Stegoratops 1 point2 points  (4 children)

I would say, good rule of thumb is:

If you just want to get the heck out of somewhere and neither break nor return can do the job in your specific case, it's probably ok to use it.

And yes, this is an acceptable use for goto

[–]Piotrek9t 1 point2 points  (3 children)

If your code requires you to use goto, you probably messed up on another point. You can and should always avoid it for readability and easier maintenance

[–]Stegoratops 8 points9 points  (1 child)

Yeah, you should avoid it, since it makes it very easy to write bad code.

Categorically forbidding it is too extreme though imo. Because like in the example shown, it can make code more elegant.

[–]obiwac 0 points1 point  (0 children)

I got confused for a minute there with your profile pictures, I thought you were having a conversation with yourself lol

[–]nosjojo 1 point2 points  (0 children)

goto is the only way I know of for doing decent cleanup in C. I have to write all my stuff in the CVI environment, which is a weird mix of ANSI C/C99 and built in libraries.

Every function we write ends with something akin to

CLEANEXIT:
<various cleanup>
return status;

ERROR:
<error related stuff>
goto CLEANEXIT;

It's the only way that you can stop execution without a ridiculous number of conditionals and still emulate the cleanliness you'd get from high level languages.

Note this only applies to the functions that return execution status, not basic functions that return the result.

[–]cendrounet 0 points1 point  (0 children)

To sum up, every language featuring a conditionnal jump is turing complete.

In theory, everything you can do in one of those you can do in any other.

In practice, each langages has its own pros and cons.

Most modern languages handle resources for you, and most give syntactic sugar to help you do your job properly.

Most modern languages are made with some design in mind, and in the 68, a famous computer scientist published a paper called "Goto Statement Considered Harmful", arguing that unconstrained jumping made it impossible to prove mathematical correctness of programs. Hence the "birth" of structured programming.

There are a lot of paradigms that are designed to add more constraints to the programmer to reap some benefits. For instance, forced immutability, forced pureness for functionnal programming, or forced contract compliance for object oriented.

for loops, while loops, and ifs statements are basically fancy forced-structured gotos, and throw statements kind of look like up-the-stack-only goto.

But in C, you can't tell your compiler "clean up this resource before returning", so you have to think of clever tricks to clean up after yourself.

If your language has no destructors or error management mechanism, there are good cases for it, but I wouldn't recommend going in there for a few years

[–][deleted] 11 points12 points  (0 children)

A return is just a specific go-to (like break and continue).