13

Labels and GOTOs are considered bad practice and as far as I know there is no reason to use it in C#.

What is the use of labels in C#?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
reshefm
  • 6,017
  • 8
  • 36
  • 40
  • 3
    They give other programmers a reason to complain about your code :-) – Ian Ringrose Mar 19 '09 at 15:59
  • possible duplicate of [Does anyone still use \[goto\] in C# and if so why?](http://stackoverflow.com/questions/6545720/does-anyone-still-use-goto-in-c-sharp-and-if-so-why) – Ian Ringrose Aug 20 '15 at 13:22

13 Answers13

23

There is nothing wrong with labels and goto's in themselves. The problem is that people tend to abuse them which does create a problem.

Typical use of a label

OperationStart:
  if ( !TrySomeOperation() ) {
    if ( MaybeFixOperation() ) { 
      goto OperationStart;
    }
  }

You'd need to make some assertions that you couldn't hit an infitite loop, but given a reasonable set of guarantees there's nothing inherently wrong with this code.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • I think this is the most common use of goto. – dr. evil Mar 19 '09 at 15:36
  • 7
    "there's nothing inherently wrong with this code" you mean except the fact that it is not very readable ? if you had it written with : while(!TrySomeOperation() && MaybeFixOperation()) {} it makes it much more obvious that you're (possibly infinitely) looping. – Aiua Mar 19 '09 at 15:38
  • 1
    -1 to Aiua's comment. *does the hand flying over head motion* – Samuel Mar 19 '09 at 15:58
  • 1
    i think this is the only one code sample where it is allowed (o; – Michael Piendl Mar 23 '09 at 14:40
  • "There is nothing wrong with labels and goto's in themselves. " -- not true. Optimizers in compilers (or in your .NET runtime) act on the fact that code is _predictable_. If you have unpredictable code, your optimizer won't be able to do anything useful with it. While your example will simply be evaluated as a loop, there are a ton of cases where labels and goto's will lead to unpredictable (and hence un-optimizable) results. This video explains a thing or two of how this actually works: https://www.youtube.com/watch?v=FnGCDLhaxKU – atlaste Feb 25 '16 at 07:48
10

Just because they are a disreputable practice, doesn't mean to should close off any possibility of using them. While they may never actually be required, they are occasionally the best way to go.

James Curran
  • 101,701
  • 37
  • 181
  • 258
7

When you are implementing a small finite state machine you can use a label for each state and goto for state transitions. This is one of the standard methods of implanting finite state machines and can lead to clear code, provided there is a diagram of the state machine in a document that the code comments point to.

Sometimes the problem domain contains lots of state machiens, (e.g. telecoms protocols are often defined by finite state machines), most of the time you don’t see finite state machine often.

Gotos and labels are also very useful for machine-generated code, if you are writing a simple compiler that outputs C# you may be very glad of them.

Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
  • DFA's are actually used quite a lot, in general they're used in tokenizers and parsers. This approach would lead to massive methods... You do know that if you have a very large method in IL, it won't be optimized by the .NET runtime, right? For various reasons it's usually better for a DFA to compile to a state pattern if you ask me - even if it's machine generated code. – atlaste Feb 25 '16 at 07:41
4

Code generators sometimes use labels and gotos. It can simplify the code generation logic in some cases. Goto statements are generally shunned for readability reasons, but if the code is not intended to be read then that is a moot point.

I have also seen cases where a decompiler gets confused enough by the IL and outputs goto statements instead of the well crafted sequence of instructions that a human would have conjured. If goto statements were not legal then the decompiler might have to completely punt on that section of code. This way, at least, it can generate something that can be round-tripped.

Brian Gideon
  • 47,849
  • 13
  • 107
  • 150
3

Why is it there?

The reason is actually pretty simple. Assembler and IL don't support advanced instructions like for, do, break, continue and while. Implicitly, code that loops (or more generally: branches) is compiled to branches. goto and label is a very literal branch.

Note that you simply cannot implement all the contraptions that I can think of easily without a 'goto'- even though there are usually better alternatives (at this point I'd like to point out that there are Design Patterns like the State pattern).

If you design a language like C#, which is kind-of the "high level assembler for IL", it only makes sense to support at least everything there is in IL. Here, branch / label is the low-level construct, and goto / label is the C# projection (with scope added as high-level construct).

From the compiler POV

Eventually if you go down to how a compiler works, there's a difference in predictable code and unpredictable code. The optimizing part of a compiler spends a tremendous amount of effort into normalizing the constructions you're using in your code. Once normalized, it's optimized using patterns.

Herein lies the problem. If you have a while loop, a for loop or a foreach loop, it will definitely generate a normalized pattern. After all, loops are the number one thing in your code that can be optimized. However, if you're using strange branches, they won't be optimized - simply because it won't be normalized to a standardized pattern and therefore won't be picked up by the pattern matcher.

This comment is not just about predictability of code patterns - it's also about predictability of data flow. Again, if it's predictable, your compiler can do more than if it's not. In various cases, constructs like break and continue will also lead to more unpredictable branches; labels and goto will just get you there more easily. The result is the same: your performance will suffer if this occurs.

So while it's true that all compilers change loops into branches of a specific form. The IL compiler is a SSA compiler, just like LLVM. This video of Chandler explains a thing or two about how this works: https://www.youtube.com/watch?v=FnGCDLhaxKU

atlaste
  • 30,418
  • 3
  • 57
  • 87
2

I think it was a marketing decision..

Microsoft wants all kinds of developers using their C# language, and if you add labels, it makes transition for some programmers easier. It also makes it easier to port old code to their language...

Arcturus
  • 26,677
  • 10
  • 92
  • 107
  • For the record: I am not a MS hater.. I am loving C# as much as the next guy.. and I think it was a smart move to add labels and goto statements... – Arcturus Mar 19 '09 at 15:44
2

Labels without goto are useless, they do nothing.

Using goto is considered a bad practice. But there is a case where it can't be avoided: breaking out of nested loops:

foreach(...) {
  foreach(...) {
    if(...) {
      goto OuterLabel;
    }
  }
}
OuterLabel:

In such a case using the break statement would just break the most inner loop.

Michael Damatov
  • 15,253
  • 10
  • 46
  • 71
  • 2
    Why not put the two foreach looks inside of there own method, then you can just use a return statement to break out. Most examples of goto I have seen are in long methods, I don't like long methods. – Ian Ringrose Mar 19 '09 at 15:47
  • Agreed, using a separate method is a good approach, because the `return` statement is able to break out of the entire method. – Michael Damatov Mar 19 '09 at 15:52
  • 7
    Some people (myself included) don't like creating methods just to create them. – Perchik Mar 19 '09 at 15:53
  • Create a method lets you give a name to the foreach loops, hence letting the code be self documenting – – Ian Ringrose Mar 19 '09 at 16:24
1

If (audience.LikesGoTo == true) { goto LabelThatSupportGoTo; } else { goto LabelForRejectGoTo; }

Ben
  • 3,241
  • 4
  • 35
  • 49
  • Did think about using [this article](http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html) for LabelForRejectGoTo. – Ben Jun 14 '12 at 23:00
1

I read somewhere, goto in most cases should just be use for jumping forward, so most likely just for early loop terminations and for continuing the outer loop since there are no labeled loops in C# (unlike Java). And there are some algorithms that can be elegantly expressed with goto than doing it the structured way.

Michael Buen
  • 38,643
  • 9
  • 94
  • 118
  • 1
    This is the way I use gotos. For nested loops, sometimes it's easier to just goto some label, instead of trying to figure out how to break out of which loop. – Perchik Mar 19 '09 at 15:41
1

It's hard to do switch statements without them.

mancaus
  • 2,983
  • 1
  • 20
  • 18
  • The case and default statements are labels. You can see this with: switch (x) { case 1: if (oneEqualsTwo) goto case 2; break; case 2: break; } This is made clearest in the ECMA spec for C#: http://www.csharpfriends.com/Spec/index.aspx?specID=15.7.2.htm – mancaus Mar 31 '09 at 09:11
0

Sometimes a well placed 'goto' is more elegant/readable than other techniques. Putting 'goto's around when they're not needed is certainly a bad practice. As always, each situation should be judged carefully.

For example, 'goto's can be nice when your function needs to do cleanups in case it fails. You place a label at the end of the function, where you do your cleanup, then 'goto' it in case of a failure.

Nevertheless, 'goto's have become less useful in C# than in C. For example, proper usage of exception handling can obviate the need of 'goto' in some scenarios.

0

The use of labels is to support goto. Bad as goto may be, if you have goto in the language, then you need labels. Without goto, labels are indeed useless in C#.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
0

While in principle I believe that there are legitimate uses for the goto statement, in practice I've been developing in C# since it was first released and I didn't know it had a goto statement until now.

Robert Rossney
  • 94,622
  • 24
  • 146
  • 218