1

I am using a goto inside of a switch statement to emulate fall through behavior.

My switch statement is using an enum to determine which case to use. When the case that contains the goto is executed, the execution hangs at that point and the hosting process starts to use a lot more cpu.

My code looks something like the following:

switch (myEnum)
{
    case HostClass.EnumType.var1: goto case HostClass.EnumType.var2;
    case HostClass.EnumType.var2: myint = 3; break;
    default: break;
}

Why does my switch statement hang on a goto? Reading online, this seems to be a common pattern.

Removing the goto fixes it, but I dont understand why.

Neil P
  • 2,920
  • 5
  • 33
  • 64
  • What is the value of EnumType.var1 and var2? Please post the declaration of that enum. – Lasse V. Karlsen Jul 16 '15 at 14:04
  • 5
    IT doesn't hang on goto, can't reproduce! – Habib Jul 16 '15 at 14:05
  • Please try to create a [MCVE](http://stackoverflow.com/help/mcve). Or, failing that, please post the actual code where you discovered this and have this problem. – Lasse V. Karlsen Jul 16 '15 at 14:08
  • http://stackoverflow.com/questions/22689392/what-is-the-better-pratice-duplicate-code-or-use-goto-statement – Only a Curious Mind Jul 16 '15 at 14:12
  • 2
    I am surprised at the number of votes and answers on this question, The code above doesn't *hang* on `goto` statement, this problem is not reproducible. – Habib Jul 16 '15 at 14:12
  • It should work. https://msdn.microsoft.com/en-us/library/13940fs2.aspx – 001 Jul 16 '15 at 14:12
  • 2
    You probably have a typo so that `goto` goes back to the same `case` label as you are in already, or you made several `goto` statements which constitute a "cycle" eventually coming back to the same label. However, your sample code does not reproduce the problem. Please take more care to include code that actually reproduces the problem you have. Otherwise people can only guess (and they will!) as to what the issue is. – Jeppe Stig Nielsen Jul 16 '15 at 14:16
  • goto case HostClass.EnumType.var2; will work if put : instead of ; , like this goto case HostClass.EnumType.var2 : – Pranay Rana Jul 16 '15 at 14:17
  • It may depend on compilation options - if I compile in debug mode I can step through the goto statement. If I compile in release mode then stepping through goes straight to the myint assignment. In both cases it works with VS2012. Maybe a poor optimisation that realises that the goto isn't necessary and makes the destination of the two cases the same, but leaves the goto in resulting in an infinite loop. – PaulF Jul 16 '15 at 14:17
  • 1
    as @Habib said its not reproducible: https://dotnetfiddle.net/yyVJRw – Juan Jul 16 '15 at 14:22
  • @Habib: all you can say is that it is not reproducible on your setup - that does not mean there is not a problem. – PaulF Jul 16 '15 at 14:36
  • 2
    Turns out I had a typo that was causing it to loop (as per @JeppeStigNielsen comment). But I was really looking for a way to fall through (as per accepted answer) – Neil P Jul 16 '15 at 14:36
  • @PaulF, I have tried it on multiple environments, there has to be some other issue.... Compiler optimization and other things could cause different behaviour *(as you said in your comment)*, but this issue is not related..EDIT... It turned out to be a typo in the code and not a real issue – Habib Jul 16 '15 at 14:39

1 Answers1

9

You don't need the goto. Just do this:

switch (myEnum)
{
    case HostClass.EnumType.var1:
    case HostClass.EnumType.var2: 
        myint = 3; break;
    default: break;
}

Update

OK, so the reason (I believe) it doesn't work is because you need a place to goto. For example:

for(var i = 0; i < 100; i+=1)
{
    if(i == 50)
    {
        goto Outer;
    }
}

Outer:
Console.WriteLine("Done");

This is a very contrived example.

I don't think this explains why your code hangs. The only thing I can think of is that the goto is waiting for an address?

As mentioned in the comments by NeilP, You can only fall through on empty case-statements. This still doesn't explain why your code hangs on 'goto'. It shouldn't.

Simon
  • 2,810
  • 2
  • 18
  • 23
  • 2
    "Removing the goto fixes it, but I dont understand why." – Sayse Jul 16 '15 at 14:04
  • Yep - sorry didn't see that bit. – Simon Jul 16 '15 at 14:05
  • 1
    Ok, so adding semicolon on the first case isn't allowed because "Control cannot fall through from one case label ('case 1:') " But without the semicolon it works. I get it now! – Neil P Jul 16 '15 at 14:06
  • 3
    @NeilP You can only fall through on empty case-statements. This still doesn't explain why your code hangs on 'goto'. It shouldn't. – Dennis_E Jul 16 '15 at 14:08
  • 1
    @simonlchilds Can you include Neil P's comment in your answer? That seemed to fix it for him. – Speerian Jul 16 '15 at 14:12
  • goto case HostClass.EnumType.var2; will work if put : instead of ; , like this goto case HostClass.EnumType.var2 : – Pranay Rana Jul 16 '15 at 14:13
  • 1
    Your update is irrelevant. You can `goto` a case label. _A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement._ - MS – 001 Jul 16 '15 at 14:18
  • Yeah, fair enough. I didn't realise you could use a goto in a switch like that. Man, I would not like to have to maintain a code base that has `goto` in a `switch`. – Simon Jul 16 '15 at 14:20
  • 1
    @simonlchilds: this is commonly used to emulate the C++ style fall-through - so not creating "spaghetti" code - it is simply a goto the very next line of executable code. (Of course, if is not going to the next line of code - you can get a nightmare) – PaulF Jul 16 '15 at 14:39
  • I see @PaulF that makes sense. – Simon Jul 16 '15 at 14:52