Tuesday, March 25, 2008

More on goto in C#

Akidan's posted a comment back on my old "goto" post from October last year, and it's got me thinking about it again. The original post was prompted by seeing gotos in .Net Framework code using Reflector, but what we were actually seeing was an optimised version of the code.

The real question comes down to code readability. A high level language like C# has constructs that make a goto statement superfluous, and a compiler which is able to recognise when a goto can replace some branching code. So from the perspective of writing high performance code, we don't need to worry: we can let the compiler figure out how best to structure the internal workings for us.

And here is the crux of the matter. If we don't need to worry so much about execution speed, then surely we should write code with an eye towards maintainability?

Now, I'm not saying that gotos make code inherently unmaintainable or unreadable: I'm willing to accept that there could be situations where they can be used, but only then used with caution.

I still stand by my belief that gotos should be avoided in code that you write yourself. Using Akidan's two methods as an example: the non-goto one is certainly more readable. It's clear that the "if" is comprised of 2 checks that results in the same outcome, and having them together like that makes it difficult to separate them later on by mistake.

3 comments:

Akidan said...

A lot of times, people speak the evils of goto, but when you ask them why, they really aren't sure. I think your post here shows a much more thought out perspective on goto.

I would agree that gotos are usually far from the best choice in terms of control flow in modern languages, and should be used with caution. Nowadays, you have quite a variety of ways to control flow at your fingertips that are often much more clear in intent than a raw goto (if, else, switch, do, for, foreach, while, break, continue, default, return, yield, throw, try, catch, finally...)

Sometimes, there aren't many good alternatives. VB6, for example, has no equivalent to the C# break keyword. The result was switch (Select Case) statements in VB could become very inefficient, because it would check all case statements for a match, one by one, even if it had already matched one of them. Since there was no break statement, the next best thing you could do was put a "goto end" at the end of each case statement instead, then put an "end" label at the end of the switch.

Despite my previous post, I avoid gotos as well... I just feel it's important to understand why we do these kinds of things, not just that we're supposed to.

Anyway, just food for thought. :)

Anonymous said...

Another thing to consider is the fact that the goto-statement IS actually part of the language. Had the goto-statement been as evil as some people say, I am sure that the c#-language design crew (Anders Hejlsberg & Co) would have left it out since they designed the language from scratch farely recently. This is of course Argument-from-authority-reasoning, but hey, they designed it, so they are the authority on C# :-)

So use it with care, but if the code looks better with a goto , then go for it...my five cents...

/Per Hultqvist

Anonymous said...

The anti-goto people are simply passing down hatred of old languages like line-numbered BASIC where goto was the only branching option available. Obviously, more structured languages are a huge improvement.

But it's pretty stupid to dogmatically insist on never using goto when using it would make the code easier to follow.