Why can't I add a goto label at the end of a method?
Asked Answered
L

7

16

After researching a way to exit a nested loop, I decided to try using goto,

private void example()
{
    for (int i = 0; i < 100; i++)
    {
        for (int ii = 0; ii < 100; ii++)
        {
            for (int iii = 0; iii < 100; iii++)
            {
                goto exitMethod;
            }                
        }             
    }

exitMethod:
}

But for some reason, if I put a goto label is at the very end of the method, Visual Studio 2012 (Ultimate) complains (and it won't compile),

Screenshot

But if I change my code to this,

private void example()
{
    for (int i = 0; i < 100; i++)
    {
        for (int ii = 0; ii < 100; ii++)
        {
            for (int iii = 0; iii < 100; iii++)
            {
                goto exitMethod;
            }                
        }             
    }

exitMethod:

    int someUnneededVariable; // Just an example, if I add ANY piece of code the error vanishes.
}

None of the errors appear (and it compiles); I've searched through all the MSDN references that I know of, and I couldn't find anything about this.

I know that I could easily solve this problem by using return;; even so, I would still like to find out what's causing this error.

Lavonna answered 30/8, 2013 at 14:25 Comment(11)
I know; but it's the principle, from my understanding this should compile, but it doesn't.Lavonna
@Sam: Nope, it really shouldn't :)Zorine
you should write some code after label. Or atlease ';' After label so that visual studio can understand that there is not more code after this.Dishonesty
Why would you use something even though you never would or should...?Aday
At least you survived the raptor attack!Devalue
@AthomSfere: It's entirely reasonable to try to understand why some code wouldn't be valid. For example, goto can be useful in autogenerated code. (async/await effectively generates a bunch of gotos.)Zorine
It's like looking at a Windows 95 batch file.Desrosiers
@JonSkeet Ah, I see what you mean, I thought a goto label didn't need a statement to label to in order to work. Thanks for your post.Lavonna
It's a shame we don't have named loops, then you could go exit loop myOuterLoopName;Plumbo
This seems silly to me. There is an implied "return" statement at the closing curly brace, it is "there" whether we write a redundant statement, or even an empty statement (just a semicolon), or not. The end of a method is a perfectly valid place to jump to. Goto's CAN be used for temporary changes while debugging, that is perfectly valid also. The compiler should not fight you over non-substantive trivialities like this. It is smarter than that. Right? Why should just adding one semicolon to denote a null statement "fix" this code? What is gained? What would be lost if it was missing?Schroer
Related question - the accepted answer is basically the same as this question's code... #6546220Schroer
Z
20

A label doesn't exist on its own: it labels a statement. From section 8.4 of the C# 5 spec:

A labeled-statement permits a statement to be prefixed by a label. Labeled statements are permitted in blocks, but are not permitted as embedded statements.

In this case, you're applying the label at the end of the method - there's no statement for it to be a label for. So the compiler is absolutely right to reject your code.

If you really wanted to, you could add a label to an otherwise-redundant return statement:

exitMethod:
    return;
}

... or just an empty statement, as suggested by Irfan. There has to be a statement though.

But I wouldn't recommend it. Just change any goto exitMethod; statement to simply return.

Zorine answered 30/8, 2013 at 14:29 Comment(4)
One may not want to return out of the enclosing method. The programmer can introduce an empty statement by simply typing a semi-colon. The compiler should do this automatically for end-of-block labels, rather than generate this confusing and unhelpful error.Tachymetry
@CNHume: If the compiler did that, it would violate the C# specification. The feature is called "labeled statements": "A labeled_statement permits a statement to be prefixed by a label." - so it would be weird not to have a statement there. You may believe you're a better language designer than the C# designers, but I suspect you'd find that permitting a label without a statement to be labeled would have unintended other consequences.Zorine
One could argue that empty statements are weird. My suggestion is just that a label immediately prior to the close of its enclosing block should be interpreted as a label on an implicit empty statement. Obviously, any specification change needs to be examined and tested carefully; but this is not a radical change. Any risk would seem confined to the semantics of multiple empty statements. This is just intuitive syntactic shorthand conforming to what some programmers naturally expect. The C# specification regularly undergoes much more dramatic changes.Tachymetry
@CNHume: We can probably agree to disagree on this - but this definitely isn't the place for a C# language feature request.Zorine
C
12

You can place blank statement.

Try:

exitMethod: ;            

But anyways, if you really want to return from current method, use return statement. if method has other return type than void,

return (type);

otherwise

return;
Cirone answered 30/8, 2013 at 14:30 Comment(0)
K
1

In this case

goto exitMethod;

is equivalent to just plain

return;

and that plan return is significantly more readable. So I don't see why would you want to do that.

Kolnos answered 30/8, 2013 at 14:28 Comment(0)
M
0

You need something for the goto to do. It cannot be blank.

For example:

private void example()
{
    for (int i = 0; i < 100; i++)
    {
        for (int ii = 0; ii < 100; ii++)
        {
            for (int iii = 0; iii < 100; iii++)
            {
                goto exitMethod;
            }                
        }             
    }

exitMethod:
    int i = DoSomething();
}
Man answered 30/8, 2013 at 14:28 Comment(1)
Well, technically he is correct. The last instruction in the method is some kind of "return" instruction and there is no reason not to put a goto label before it. But why.Kolnos
K
0
"The goto statement transfers the program control directly to a labeled statement." 

You have exitMethod as your label, but in your first example you have no statement. This is why you are getting an error.

goto reference

Kremenchug answered 30/8, 2013 at 14:29 Comment(0)
A
-1

You are missing a semicolon try this:

exitMethod:;
Annettaannette answered 29/11, 2023 at 0:3 Comment(1)
Thanks for becoming a contributor to the community! Your answer appears to be correct. However, note that another answer from years ago already offers exactly the same advice. A good answer will also provide context. For example, rather than just providing an answer, elaborate on why it works.Pennate
O
-2

Two things, first goto is NOT recommended. It will not allow you to use a label like that because of how labels work. A label is a source code only identifier allowing you to point to a specific instruction. In the case you're attempting, there is no instruction following it, and thus it cannot resolve to the location of an instruction. This is causing your error.

Again, you shouldn't be using a goto in this way. If you simply need to exit the function, you can use a return; statement. If the coding standard you're using dictate only a single return point, then try something like this:

private void example()
{
    bool escaping = false;
    for (int i = 0; i < 100 && !escaping; i++)
    {
        for (int ii = 0; ii < 100 && !escaping; ii++)
        {
            for (int iii = 0; iii < 100 && !escaping; iii++)
            {
                escaping = true;
                break; // this is only needed if there is code farther down this 
                       // inner loop that would otherwise be executed.
            }                
        }             
    }

return;
}
Orcein answered 30/8, 2013 at 14:33 Comment(1)
If the OP wants to make a temporary change to the code while debugging it or modifying it, Goto is a useful temporary change to make. Your change is much harder.Schroer

© 2022 - 2025 — McMap. All rights reserved.