Alox
Alox

Reputation: 671

Fall from one case to another using goto

I have read multiple articles saying using goto is a massive no no in programming. But some specifically indicate that it's the abuse of goto that is wrong and that in some cases, like switch cases, it's the intended use.

So my question to you is, for future reference, which is best practice/more efficient.

this:

switch (a)
{
    case 1:
        //Something specific for case 1
        break;
    case 2:
        //Something specific to default and case 2
        break;
    default:
        //Something specific for default
        goto case 2;
}

or this:

switch (a)
{
    case 1:
        //Something specific for case 1
        break;
    case 2:
        //Something specific to default and case 2
        thatFunction();
        break;
    default:
        //Something specific for default
        thatFunction();
        break;
}

void thatFunction() { /*Case 2 stuff*/ }

EDIT: These two switch statements are examples, the actual code contains many more cases.

Everyone at my workplace has either never used goto or say they've only heard to never ever use it. So I came here for a definitive answer. I'm looking for an answer and an explanation or links to one. Thanks,

Upvotes: 1

Views: 1070

Answers (2)

Luaan
Luaan

Reputation: 63742

You always need to understand the reasoning behind any "no-no" (or "yes-yes"). That way you can understand where it makes sense to apply the rule, and where it doesn't.

The big fight against goto goes all the way back to programming without true procedures and functions, or even something as simple as a loop. goto allowed you to jump from anywhere to anywhere else, and it was extremely hard to think about what it actually means. "Don't use goto" was part of the movement to structured code, as opposed to lots of jumps all the way around the code; using things like for (int i = 10; i > 0; i--) { ... } for iteration, rather than if (i-- > 0) goto startLoop;.

In a switch, goto is constrained - it can only do one thing, execute a branch of the switch statement. In fact, in C#, even outside of a switch statement, goto is very constrained and safe, and rarely has any of the implications that were assumed when the "Goto is evil" movement started. That doesn't mean you should start replacing all your loops with gotos, of course :)

Now, if things are getting this complicated, it might be that a switch isn't a good solution for your problem in the first place. Perhaps you can use a different structure to do what you're trying to do - there's many ways to do polymorphism and/or code reuse in C#, and one of those might be a better approach that will allow you to use clearer code to do what you're trying to do. But we can't really help you with that :)

Upvotes: 3

CDove
CDove

Reputation: 1950

The answer is that logic going in circles is best kept to religion and politics. Your default is really case 2, which means that case 2 is really just default. While it's possible that there's some execution in case 2 that doesn't occur in default, it's extremely rare that you'd ever need to do anything other than an if condition in your default case. Further, in troubleshooting the result of your switch evaluation cannot be immediately determined if you loop backward up the case chain. Imagine your stack trace, too.

There are times to use goto, but these are often in exceptional cases (see what I did there) where you need to immediately execute an action (such as logging something going wrong on another thread) before breaking a run condition or infinite loop. The general rule with goto is the same as with preprocessor commands. If there's another way you can do the same effective thing, you should use the other way for logical continuity and maintainability.

Upvotes: 1

Related Questions