Fall from one case to another using goto - c#

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,

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 :)

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.

Related

Is it possible to always eliminate goto's?

While making everthing with goto's is easy (as evidenced by f.ex. IL), I was wondering if it is also possible to eliminate all goto statements with higher level expressions and statements - say - using everything that's supported in Java.
Or if you like: what I'm looking for is 'rewrite rules' that will always work, regardless of the way the goto is created.
It's mostly intended as a theoretical question, purely as interest; not as a good/bad practices.
The obvious solution that I've thought about is to use something like this:
while (true)
{
switch (state) {
case [label]: // here's where all your goto's will be
state = [label];
continue;
default:
// here's the rest of the program.
}
}
While this will probably work and does fits my 'formal' question, I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
So, is there a better solution?
Update 1
Since a lot of people seem to think the question is 'too broad', I'm going to elaborate a bit more... the reason I mentioned Java is because Java doesn't have a 'goto' statement. As one of my hobby projects, I was attempting to transform C# code into Java, which is proving to be quite challenging (partly because of this limitation in Java).
That got me thinking. If you have f.ex. the implementation of the 'remove' method in Open addressing (see: http://en.wikipedia.org/wiki/Open_addressing - note 1), it's quite convenient to have the 'goto' in the exceptional case, although in this particular case you could rewrite it by introducing a 'state' variable. Note that this is just one example, I've implemented code generators for continuations, which produce tons and tons of goto's when you're attempting to decompile them.
I'm also not sure if rewriting in this matter will always eliminate the 'goto' statement and if it is allowed in every case. While I'm not looking for a formal 'proof', some evidence that elimination is possible in this matter would be great.
So about the 'broadness', I challenge all the people that think there are 'too many answers' or 'many ways to rewrite a goto' to provide an algorithm or an approach to rewriting the general case please, since the only answer I found so far is the one I've posted.
This 1994 paper: Taming Control Flow: A Structured Approach to Eliminating Goto
Statements proposes an algorithm to eradicate all goto statements in a C program. The method is applicable to any program written in C# or any language that uses common constructs like if/switch/loop/break/continue (AFAIK, but I don't see why it wouldn't).
It begins with the two simplest transformations:
Case 1
Stuff1();
if (cond) goto Label;
Stuff2();
Label:
Stuff3();
becomes:
Stuff1();
if (!cond)
{
Stuff2();
}
Stuff3();
Case 2
Stuff1();
Label:
Stuff2();
Stuff3();
if (cond) goto Label;
becomes:
Stuff1();
do
{
Stuff2();
Stuff3();
} while (cond);
and builds on that to examine each complex case and apply iterative transformations that lead to those trivial cases. It then rounds off with the ultimate gotos/labels eradication algorithm.
This is a very interesting read.
UPDATE: Some other interesting papers on the subject (not easy to get your hands on, so I copy direct links here for reference):
A Formal Basis for Removing Goto Statements
A Goto-Elimination Method And Its Implementation For The McCat C Compiler
A situation where a goto can be avoided, but I think it is better to use it:
When I need to exit a inner loop and the loop:
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
for(int j = 0; j < inner.Count; j++)
{
// Some code.
if (condition) goto Finished;
}
}
Finished:
// Some more code.
To avoid the goto you should do something like this:
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
bool conditon = false;
for(int j = 0; j < inner.Count; j++)
{
// Some code that might change condition
if (condition) break;
}
if (condition) break;
}
// Some more code.
I think it looks much nicer with the goto statement.
The second situation is okay if the inner loop was in a different method.
void OuterLoop(list)
{
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
if (InnerLoop(inner)) break;
}
}
bool InnerLoop(inner)
{
for(int j = 0; j < inner.Count; j++)
{
// Some code that might change condition
if (condition) return true;
}
return false;
}
I have some practical experience of attempting to take an unstructured program (in COBOL, no less) and render it as structured by removing every instance of GOTO. The original programmer was a reformed Assembly programmer, and though he may have known about the PERFORM statement, he didn't use it. It was GOTO GOTO GOTO. And it was serious spaghetti code -- several hundred lines worth of spaghetti code. I spent a couple of weeks worth of spare time trying to rewrite this monstrous construct, and eventually I had to give up. It was a huge steaming pile of insanity. It worked, though! Its job was to parse user instructions sent in to the mainframe in a textual format, and it did it well.
So, NO, it is not always to possible to completely eliminate GOTO -- if you are using manual methods. This is an edge case, however -- existing code that was written by a man with an apparently twisted programming mind. In modern times, there are tools available which can solve formerly intractable structural problems.
Since that day I have coded in Modula-2, C, Revelation Basic, three flavors of VB, and C# and have never found a situation that required or even suggested GOTO as a solution. For the original BASIC, however, GOTO was unavoidable.
Since you said it's a theoretical question, here is the theoretical answer.
Java is Turing complete so of course, yes. You can express any C# program in Java. You can also express it in Minecraft Redstone or Minesweeper. Compared to these alternatives expressing it in Java should be easy.
An obviously more practical answer though, namely an intelligible algorithm to do the transformation, has been given by Patrice.
I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
That's what you're always going to get when looking for a general pattern which can replace any use of goto, something which does exactly the same as a goto would do. What else could it be? Different uses of goto should be replaced with best matching language construct. That's why constructs as switch statements and for loops exist in the first place, to make it easier and less error prone to create such a program flow. The compiler will still generate goto's (or jumps), but it will do so consistently where we will screw up. On top of that we don't have to read what the compiler generates, but we get to read (and write) something that's easier to understand.
You'll find that most compiler constructs exist to generalize a specific use of goto, those constructs where create based on the common patterns of goto usage which existed before it. The paper Patrice Gahide mentions sort of shows that process in reverse. If you are finding goto's in your code you are either looking at one of those patterns, in which case you should replace it with the matching language construct. Or you are looking at essentially unstructured code in which case you should actually structure the code (or leave it alone). Changing it to something unstructured but without goto can only make matters worse. (The same generalization process is still going on by the way, consider how foreach is being added to compilers to generalize a very common usage of for...)

Why not force explicit fall-through rather than explicit break for switch statements?

This is not specifically a C# question but it is the C# version of switch that makes me ask the question.
Why do I have to explicitly state that I do not want to fall through from one case statement to the next instead of instead indicating when I DO want to fall through?
In C#, the compiler will not let you fall through from one case statement to the next (unless the case statement is empty) and yet it forces you to put an explicit break at the end of every one. The vast majority of switch statements that I write have no fall through.
int x = 4;
string result;
switch (x)
{
case 1:
result = "One";
break;
case 2:
result = "A couple";
break;
case 3:
case 4:
result = "Three or four";
break;
/*
case 5:
result = "Five"; // Here be an error! A common typo for me!!!
*/
default:
result = "Five or more";
break;
}
The above example is contrived to show the possibilities. The number of times I actually fall-through (like between 3 and 4 above) is minimal. If I remove the comments from case 5 above, the C# compiler will catch it as an error. Why do I have to fix it manually if the compiler knows full well what I am trying to do?
Wouldn't the following be better?
int x = 4;
string result;
switch (x)
{
case 1:
result = "One";
case 2:
result = "A couple";
case 3:
continue; // or even goto 4
case 4:
result = "Three or four";
/*
case 5:
result = "Five"; // This would not longer be an error!! Hooray!
*/
default:
result = "Five or more";
}
Let me be clear that I am not advocating fall-through here. There is an implied break at the end of every case statement. The two examples are meant to be functionally equivalent.
The compiler could still yell at me if I forgot the continue statement in case 3. This would not happen very often though and I would be happy for the help. In fact, the chance that I just missed filling in the skeleton code is pretty high in this case. Useful. Telling me that I forgot a break statement is never helpful. It is just more busy-work to keep the compiler happy.
It seems like this is probably just a hold-over from C (which does allow you to fall through even when you have code in the case statement). Is there a deeper reason that I do not see?
I was looking at some compiler code just this morning and there were hundreds of case statements in a switch that did nothing but return op-codes. Every one of them had a break statement. So much typing and clutter...
What do people think? Why is the second option not a better default?
The rationale for C# switch statements is that C's behavior is that cases fall through unless you explicitly exit with a statement like break, return, or goto. This means that everybody who is familiar with C (which is probably most C# programmers) will be expecting the C# switch syntax to mean approximately the same thing. If the C# designers made cases not fall through, code would do the exact opposite of what users will expect!
On the other hand, it's a common source of bugs for people to forget the break statement at the end of a case and have control fall through where it wasn't supposed to. A less common problem is that people will re-order the cases such that the one which used to be at the end (and not need a break) is no longer at the end (and falling through unexpectedly).
In other words, making cases not fall through would cause bugs from people who are expecting it to fall through, but not requiring the explicit termination of the case would cause bugs from people who forgot to put in a break. Thus, cases can't fall through, but a break is still required.
switch statements really shine in the case when things like this happen (to replace ifs)
switch (my_var) {
case 1:
case 2:
case 3:
case 4:
do_something();
break;
case 5:
case 6:
case 7:
case 8:
do_something else();
break;
}
This replaces heavily either nested ifs, or giant if statements with ands in them.
The other main reason is that it is kind of brought back from C. Case statements look almost exactly like the assembly that would be generated by the compiler for them (in some cases). Not really too sure why they went with this design at first but I really see no issue as the same number of if's might also seem cluttered (not always though).
C# probably see's the missing break as an error (common one at that) and probably that's the reason for flagging it. It usually only does this with the last one that falls through to the default statement and the default statement itself has to have a break (because you can always put the default at the beginning). C# tries to be strict in this sense so as to avoid some simple bugs that can be caused by simply forgetting to type break at the end of every case (or some case) and having it fall through execution.
The reason that C and C++ have implicit fall-through is backward compatibility with a tremendous amount of code that depends on it, even though rarely.
The reason that C# doesn't have implicit fall-through is that it's a bug in most cases. The reason that C# doesn't have implicit break is that it would be a surprise to C, C++, and Java programmers. And it wouldn't even generate a warning? Silent unexpected failures are very bad.
Requiring the behavior to be explicit is the safest option, and that's the route C# took. (and I wish that C++ would develop an explicit syntax for fall-through, so that compilers could warn about implicit fall-through)

Does anyone still use [goto] in C# and if so why? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I was wondering whether anyone still uses the "goto" keyword syntax in C# and what possible reasons there are for doing so.
I tend to view any statements that cause the reader to jump around the code as bad practice but wondered whether there were any credible scenarios for using such a syntax?
Goto Keyword Definition
There are some (rare) cases where goto can actually improve readability. In fact, the documentation you linked to lists two examples:
A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.
The goto statement is also useful to get out of deeply nested loops.
Here's an example for the latter one:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
Of course, there are other ways around this problem as well, such as refactoring the code into a function, using a dummy block around it, etc. (see this question for details). As a side note, the Java language designers decided to ban goto completely and introduce a labeled break statement instead.
I remember this part
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
To something like this
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Refer This
I use it extensively in Eduasync to show the kind of code that the compiler generates for you when using async methods in C# 5. You'd see the same thing in iterator blocks.
In "normal" code though, I can't remember the last time I used it...
The compiler uses goto statements in various pieces of generated code, for example in generated iterator block types (generated when using the yield return keyword - I'm pretty sure that the generated XML serialisation types also have a few goto statements in there somewhere too.
See Iterator block implementation details: auto-generated state machines for some more details on why / how the C# compiler handles this.
Other than generated code there isn't a good reason to use a goto statement in normal code - it makes the code harder to understand and as a result more error-prone. On the other hand using goto statements in generated code like this can simplify the generation process and is normally fine because nobody is going to read (or modify) the generated code and there is no chance of mistakes being made because a machine is doing the writing.
See Go-to statement considered harmful for an argument against goto as well as a classic piece of programming history.
I don't remember ever using goto. But maybe it improves the intent of a forever loop that you really never want to exit (no break, but you can still return or throw):
forever: {
// ...
goto forever;
}
Then again, a simple while (true) should suffice...
Also, you could use in a situation where you want the first iteration of a loop to start in the middle of the loop: look here for an example.
goto is great for breaking out of many loops where break would not work well (say upon error conditions), and as Kragen said goto is used by the compiler to generate switch statements and some other things as well.
The processor implements at least one jump instruction and I'm sure lots of statements use those in thier implementation or interpretation.
One of the good things about using a 3rd or 4th generation langauge is that these physical details are abstracted away from us. Whilst we should be mindful of the law of leaky abstraction I think that we should also use our tools as they are intended (sorry). If I were writing code and a goto seemed like a good idea, it would be time to refactor. The purpose of a structured language is to avoid these "jumps" and to create a logical flow in our engineering.
I should avoid the use of break but I can't overlook the performance benefit. However, if I have nested loops that mutually need to break it is time to refactor.
If anybody can propose a use of goto that seems better than refactoring I will gladly withdraw my answer.
I hope I'm not guilty of rushing to the "bike shed" here. Like Kragen says, whats good enough for Dijkstra is good enough for me.
Goto is never better. And continue, break (except in switch/case), (multiple) return, and throw should also be kept to the barest minimum. You never want to escape from the middle of nest loops. You always want the loop control statements have all the loop control. Indenting has information, and all these statement throw that information away. You might as well take out all the indenting.

Why do you need to put break after the last label of a switch statement?

Surely the compiler knows that it's the last label of the switch statement?
Having a break after your switch's final case statement is good defensive programming. If, perhaps in the future, another case statement is added below, it removes the risk of the program's flow falling through from the case above.
It's because in C++ this is what happens:
switch(a)
{
case 1:
// do stuff
case 2:
// do other stuff
}
If a is 1, then - according to C++ rules - both "do stuff" and "do other stuff" would happen. So that C++ programmers coming to C# do not get tripped up (and to make code clearer all 'round), C# requires that you explicitly specify whether you want to break or fall through to a different label.
Now, as for why you need the break on the last block, that's a simple matter of consistency. It also make re factoring easier: if you move the cases around, you don't suddenly end up with errors because of a missing break statement. Also, what happens when you want to add another label, etc, etc.
Consistency. Same reason as being able to have a comma after the last enum definition or the last assignment in an object instantiation statement with braces. And the last case might not always be the last case.
It also makes it so there are fewer special cases.
And if that's the case, then it is easier to learn, write, or read. Although that adds to the consistency thing.
In C# switch statements you must explicitly state to break or goto another case or goto default.
In C and C++, switch statements have fall through labels without a break. Having the user explicitly say what they want to do is important in C# to avoid bugs. A lot of users come to C# from C++ for example.
About the last case statement in particular that you're asking about. I can think of 3 good reasons.
It's important to keep things consistent in any language.
What if you append another case after it later on, what should be done with default?
Why should break be the default? Why not goto? There is ambiguity here.
According to http://msdn.microsoft.com/en-us/library/06tc147t.aspx
You cannot "fall through" any switch section, including the last one.
Fall through can be avoided by any of the following: break, goto, or return.
Actually There is one case when you don't have to put break
Consider this code:
using System;
public class Program
{
public static void DoStuff()
{
}
public static void DoAnotherStuff()
{
}
public static void Main()
{
switch(1)
{
case 1: DoStuff(); break;
default: DoAnotherStuff();
}
}
}
Using C# 4.0 compiler it only gives you a nice CS0162: Unreachable code warning
It appears that since switch has a constant expression the compiler already knows wich path it's going to execute, then just ignores the dafault label.
The cool thing is that if you change switch(1) to switch(2) it no longer compiles because the default label lacks its break.
Edit: From the C# Reference
The requirement in C# is that the end of every switch section, including the final one, is unreachable. Although this requirement usually is met by using a jump statement, the following case also is valid, because the end of the statement list cannot be reached.
case 4:
while (true)
Console.WriteLine("Endless looping. . . .");
That explains why the default does not need a break. In fact any unreacheable label doesn't need a break nor return nor goto
When using a switch, to break is not the only option. You also have the option of going to another case, going to the default case, going to another label, or returning. It is also possible to have multiple cases that have a single implementation body. Since there are up to five options plus the ability to have multiple cases for one implementation, the compiler is not able to simply put in the "correct" answer.
You have to choose what you intend to do. It ensures the compiler does the right thing, makes your code clearer, and makes it more difficult to do dumb-programmer-things, like add another case after the "last one", and forget to put in a break/goto/return.
According to this blog post by Eric Lippert (Case 2), it allows you to be able to arbitrarily re-order your switch sections without accidentally introducing a breaking change:
It [the compiler] requires that every switch section,
including the last one, have an
unreachable end point. The purpose of
this rule, and of the no-fall-through
rule in general, is that we want you
to be able to arbitrarily re-order
your switch sections without
accidentally introducing a breaking
change.
As mentioned, you can use default:, but consider case null too. case null: does need a break;
case null:
iEvaluatedToNothing();
break;
If you want to "waterfall" down you can do something like this;
switch (deliverMail)
{
case null:
case "":
case "Address0":
deliverMail0();
goto case "1";
case "1":
deliverMail1();
break;
}
You can use this with breaks as needed, but one is required on the last evaluation.

does this switch statement smell bad? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Switch(some case) {
case 1:
// compute something ...
return something;
break;
case 2:
// compute something ...
return something;
break;
/* some more cases ... */
case X:
// compute something ...
return something;
break;
default:
// do something
return something;
break;
}
In my opinion:
Assuming this switch statement is justifiable, the return and break just doesnt look right or feel right.
The break is obviously redundant, but is omission poor style (or is this poor style to begin with?) ?
I personally dont do this, but there is some of this in the codebase at work. And no, im not going to be self-righteous and correct the codebase.
No, omission is not poor style - inclusion is poor style. Those are unreachable statements. Get rid of them.
I like the fact that the cases return directly instead of setting a local variable and then returning just at the bottom - it means that it's incredibly clear when you're reading the code that it does just need to return, and that's all.
Side-note in terms of switching in the first place:
As for whether using a switch statement is the right thing to do here, it really depends on other things. Would it make sense to use a polymorphic type instead? If you're in Java, could you use a smart enum? (You can mimic these in C#, but there isn't as much support.)
I'd say this should at least prompt considering different designs - but it may well be the simplest way to do what you want.
The C# Compiler gives a warning if you do this saying that the break is unreachable code. So in my book it is bad form to have both return and break.
In my opinion, I would omit the 'break' keyword. I personally think it helps remind people that 'Execution has ended! Nothing more to see here!'.
I would make a small change:
switch(some case) {
case 1:
// compute something ...
break;
case 2:
// compute something ...
break;
/* some more cases ... */
case X:
// compute something ...
break;
default:
// do something
break;
}
return something;
I'm not sure how literal that code is intended to be so some of these observations may not be applicable...
"case 1"
If you're truly hard-coding numers like this I think it is poor style and you should look into using an enumeration.
If you are simply returning something and there is no additional logic in a subset of the cases, you might consider putting the "somethings" in an array or dictionary and simply addressing them by their index rather than using a switch statement...
return somethings[index]
Code smell implies a design problem. This is just an issue of formatting. I think most people would agree that a version with breaks omitted is superior.
The break is redundant.
Some rule of thumb, It is always good to exit a function in one place only, But since this rule was made Try-Catch was invented (oop goto).
If you keep the same style all over your application, I guess you can live with the return in the switch.
The code smell here is the hard coded values in the case statements.
As for the returns it is more a question of taste and good judgement. Sure if your case spans mutiple pages it is easier to read if the return is in the case, but then the problem is the big switch to begin with.
Personnaly I prefer the single return option because if ever you need to add some more processing then it is cheaper to refactor than visiting all the cases. Also, if given to someone else to refactor they will not have the temptation to copy paste the code in every case, least I would hope so ... if they do they better hope I am not the one doing their code review (for the copy paste obviously).
Switch statements are themselves a code smell.
Along the lines of what l99057j said, if all you're doing is mapping inputs to constant values, this is a place for an appropriate lookup structure, such as an array/list for sequential inputs or a dictionary/map for a sparse one, not a switch statement. If you're calculating something, then the value would be a delegate that you call with the input.
Others have commented on other aspects. As for the breaks that are redundant after the returns: I would KEEP them, along the same reasoning as { } around a single-statement if body: it should be second nature for every programmer to put those braks there. Better have 100's of such redundant breaks than one unintentionally missing.

Categories