SIGN UP MEMBER LOGIN:    
ARTICLE

Acceptable uses for the goto statement in C#

Posted by Vulpes Articles | C# Language April 05, 2011
In those days, he had a point because the 'goto' statement produced a lot of spaghetti code particularly by those using early versions of the BASIC programming language.
Reader Level:

Introduction

There has been a lot of hysteria about the 'goto' statement since the famous computer scientist, Edsger Dijkstra, said in 1968 that he considered it to be "harmful".

In those days, he had a point because the 'goto' statement produced a lot of spaghetti code particularly by those using early versions of the BASIC programming language.

Despite this warning, 'goto' was included in C, C++ and C#. It wasn't included in Java though they do have labelled 'break' and 'continue' statements which achieve much the same thing.

In C#, it's much tamer than in some other languages as you can't jump into a nested block; you can only jump out of (or within) one. As far as the compiler is concerned, it works quickly because it can be mapped directly to CIL, and thence to native code, 'jump' instructions.

Although 'goto' isn't needed much in modern programming and it's always possible to program around it, I believe its use is acceptable in certain scenarios which I'd like to examine in this article. The scenarios presented are not necessarily exhaustive.

Jumping between 'case' blocks in a 'switch' statement

Unlike C, C++ and Java, C# doesn't permit code to 'fall through' from one case block to another unless the first case block is empty. This eliminates some potentially hard to find bugs. If you do need to fall through, you can use the 'goto case' construct instead:

string position = "first"
switch (position)
{
    case "first":
        DoSomething();
        goto case "second"; // not allowed to 'fall through' here
    case "second":
        DoSomethingElse();
        break;
}

This is nice and clean and I don't think many C# developers would quarrel with this usage.

Jumping out of (or within) deeply nested loops

The 'break' statement only jumps out of the current loop. If you want to exit from two or more nested loops, then the usual solution is to use bool variables in the following manner:

bool finished = false
for (int i = 0; i < 10; i++)
{
    while (someCondition)
    {
        //  ....
        if (someOtherCondition)
        {
            finished = true;
            break;
        }
    }
    if (finished) break;
}

Now, this is a reasonable solution when you only have two nested loops but, if you have more than this, then it can become unwieldy and error prone. In this situation, using 'goto' is much simpler and clearer:

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        while (someCondition)
        {
            //  ....
            if (someOtherCondition)
            {
                goto finished;
            }
        }
    }
}
 
finished:
// code following loops

Similar considerations apply to the 'continue' keyword which can only continue the current loop. If you want to continue an outer loop, then 'goto' can be used instead of bool variables:

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        while (someCondition)
        {
            //  ....
            if (someOtherCondition)
            {
                goto continuation;
            }
        }
    } 
   continuation: ; // empty statement here
}

Although having to jump to an empty statement is rather ugly, it's usually cleaner than the alternatives.

Retrying code after making corrections

The situation sometimes arises where you'd like to try a piece of code and, if it fails, make a correction and try it again. As C# lacks a 'retry' statement, you might come up with code such as this:

int x = 4, y = 0;
int z;
bool success;
 
do
{
    success = true;
 
    try
    {
        z = x / y;
    }
    catch (DivideByZeroException)
    {
        y = 2;
        success = false;
    }
 
} while (!success);
 
Console.WriteLine(z);

This works and isn't too bad but using 'goto' is cleaner and clearer:

int x = 4, y = 0;
int z;
 
retry:
try
{
    z = x / y;
}
catch (DivideByZeroException)
{
    y = 2;
    goto retry;
}
Console.WriteLine(z);

Conclusion

I should warn you now that prejudice against the 'goto' statement runs very deep and its use is often banned by some programming teams. However, I hope I've demonstrated that there are a few scenarios where its use may be beneficial so don't ignore it, if you have the choice!

erver'>
Login to add your contents and source code to this article
share this article :
post comment
 

It would be great if you could, Sam, as I'm a strong believer in letting people see both sides of the argument before coming down on one side or the other.

Posted by Vulpes Apr 05, 2011

I suppose I should write an article about how to avoid goto. For example, instead of branching (goto-ing) from one case to another, it is totally possible to put the common code in a function and call the function.

Posted by Sam Hobbs Apr 05, 2011

Like you, I've had to struggle with maintaining other people's spaghetti code and sometimes I've given up and rewritten it from scratch. If it were still possible in C# to jump into blocks, then I wouldn't have written this article. However, C#'s 'goto' is much tamer than those of old and my concern now is that using a series of bool variables, in order to avoid goto, can also lead to code which is hard to understand and maintain. The problem, of course, is that you can get carried away and start using goto when you shouldn't (even now I still see beginners doing this) but the point I wanted to make is that the occasional judicious use of goto may be beneficial and that the language designers wouldn't have put it in if they thought it would cause more harm than good. I accept, of course, that my examples are oversimplified and that real world scenarios will usually be less clear-cut.

Posted by Vulpes Apr 05, 2011

I have had the job of untangling spaghetti code. I have untangled code that was much more of a mess than I hope anyone else reading this can imagine. The simple code that you show is not representative. The problem is that when a program with gotos is modified, it often gets more complicated and the complications can multiply. Imagine a long length of string. It gets tangled a little bit. So it can be untangled. What if it gets very tangled, and then it can easily get much more tangled. Sometimes string becomes so tangled that it is just thrown in the trash. I have seen code so complicated that most programmers could not successfuly modify the code. Absence of gotos does not guarantee clean code and I admit that anyone that writes good clean code can do it with gotos but the problem is that gotos can increase the complexity of programs faster when gotos are used by some people.

Posted by Sam Hobbs Apr 05, 2011
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor
PREMIUM SPONSORS
  • Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites - Click Here!
    Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor