Friday, February 27, 2015

Why is there a goto in my code

As I've explored before, the Unity team has made design decisions that force the programmer to use bad coding practices. As I've spent the past couple of months working with Unity, I've developed a love/hate relationship with it. Mostly what fuels my love is that I can use C# which is my favorite language to program in, though Mono isn't helping. It shocked and surprised me when my programming team was working on a problem for the next build had to put in a goto statement. We had a switch case in which we needed a case to fall through to the next case. This is done easily in C++.

switch(condition)
{
    case 0:
    case 1:
        // do some code
        break;
    case 2:
        // do some code
    default:
        // shared code
        break;
}


C# is different in that the fallthrough from case 0 to case 1 is allowed but the fallthrough from case 2 to default is not allowed. In order to get the fallthrough this is what must be done.

switch(condition)
{
    case 0:
    case 1:
        // do some code
        break;
    case 2:
        // do some code

        goto default;  
    default:

        // shared code
        break;
}


It should be obvious why this looks bad. Goto's have been the boogeyman of software engineering that allows subtle bugs and destroys good control flow. It's hatred is so universal that the first rule at many to all software companies is to never use them. Then why did the people at Microsoft decide to use goto to explicitly declare a fallthrough?

Not explicitly declaring a fallthrough does cause subtle bugs as it is possible to forget to include a break and have the code fall through to the next case. In order to avoid allowing programmers to avoid this subtle bug, they had two choices: declare a new keyword or use an old keyword. Declaring a new keyword, such as fallthrough, would give the programmer one less choice of a variable name and add complexity to their work of implementing it into the compiler. Using an old keyword, they had two choices: continue and goto. Goto isn't used as much, or at all, as continue and is a better choice as a case is a label and switching a condition is basically a goto. So the goto was the best choice given these assumptions.

I believe there is a better solution to this problem. Apple released a new, unfinished, language called swift so that mobile developers don't have to use Objective-C to write iOS apps. In their switch-case, there is no break. Each case breaks by default and in order to fallthrough that keyword has to be explicitly declared. I like this paradigm since it avoids the subtle fallthrough bugs and takes out the work of always writing break. I don't think Microsoft will do this since it does require an overhaul of how the compiler handles switch-case.

Does it suck that there is a goto statement in the codebase, yeah. However, this use of goto is useful because that's the only way to fallthrough to the next case so we don't have to replicate code. It's also not used in a way that breaks codeflow or creates subtle bugs from jumping out of a method from multiple mid-method points.

No comments:

Post a Comment