11.6 Flow control with the goto keyword


11.6 Flow control with the goto keyword

Yes, goto is still there in C#, although the makers of Java got rid of its functionality (still reserving the goto keyword) when they designed Java from C++. Nevertheless, do you realize that if you have been using labels in Java, and break -ing or continue -ing to such labels, you are actually performing a pseudo goto (without the goto keyword)?

There are three ways to use C#'s goto :

  • goto case <expression> ;

  • goto <label> ;

  • goto default ;

11.6.1 Using goto in switch-case blocks

goto can be quite useful in switch - case blocks too, since 'falling-through' case blocks is no longer supported in C#.

Their use should be clear from this example (see section 11.4):

 1:  using System;  2:  3:  class TestClass{  4:    public static void Main(){  5:      int i = 1;  6:  7:      switch(i){  8:            case 1 : Console.WriteLine("ONE");  9:  goto case 3  ; 10: 11:            case 2 : Console.WriteLine("TWO"); 12:                     break; 13: 14:            case 3 : Console.WriteLine("THREE"); 15:  goto default;  16: 17:            default : Console.WriteLine("DEFAULT"); 18:                      break; 19:      } 20:    } 21:  } 

Output:

 c:\expt>test ONE THREE DEFAULT 

Study line 9 which shows how the goto case expression is used to force both the case 1 and case 3 blocks to be executed in the event when i ==1.

11.6.2 Using goto <label>

If you use labels in Java, you can use the break and continue statements to force execution flow to continue from a particular label. C#'s break and continue keywords do not take in a label “ you use C#'s goto <label> to exit an outer loop from an inner loop prematurely. Instead of labeling the loop (which you do in Java), you label a statement outside the loop you want to break out of, and goto that statement.

Study this example:

 1:  using System;  2:  3:  class TestClass{  4:    public static void Main(){  5:  6:      for (int i=0; i<5; i++){  7:        for (int j=0; j<5; j++){  8:          Console.WriteLine(i+","+j);  9:          if (j==3) 10:  goto End;  11:        } 12:        Console.WriteLine("skipped"); 13:      } 14: 15:  End:  // arbitrary label 16:        Console.WriteLine("end"); 17:    } 18:  } 

Output:

 c:\expt>test 0,0 0,1 0,2 0,3 end 

Because of the goto End; statement on line 10, line 12 will never get to execute since the inner for loop never completes.

However, the following code does not compile:

 1:  using System;  2:  3:  class TestClass{  4:  5:    public static void Main(){  6:  7:  goto InsideLoop;  8:      for (int i=0; i<5; i++){  9:  InsideLoop:  10:          Console.WriteLine("looping"); 11:      } 12:    } 13:  } 

Compilation warnings and error:

 test.cs(8,5): warning CS0162: Unreachable code detected test.cs(7,5): error CS0159: No such label 'InsideLoop' within the scope of the goto statement test.cs(9,7): warning CS0162: Unreachable code detected test.cs(9,7): warning CS0164: This label has not been referenced 

Line 8 is unreachable, and the compiler generates a warning (not an error though). The error thrown by the compiler is what I want to draw your attention to “ ' InsideLoop ' is not within the scope of the goto statement, since it is in a for loop. You can jump from inside a loop to outside, but not from outside to inside. [7] Even if you shift line 7 to between lines 11 and 12, you will still get the same compilation error.

[7] Wouldn't it be messy if you could jump right into the middle of a loop? Obvious ambiguities include deciding which iteration it will be. It's for that reason that you are not allowed to hop into a statement in the middle of a loop using goto <label> .

If a label is specified but not used, the compiler will give a warning that the label has not been referenced. In the code example above, if line 7 is deleted but the label of line 9 is kept, the class compiles with a compilation warning, but runs fine.

11.6.3 Misusing the goto keyword

Although you can jump around blocks of code using labels and the goto <label> statement, you should restrict its use to breaking out from inner loops .

Here's an example of how the goto <label> statement can be legally abused.

 1:  using System;  2:  3:  class TestClass{  4:  5:    public static void Main(){  6:  7:  Label1:  8:        Console.WriteLine("never ");  9:  goto Label2;  10: 11:  Label2:  12:        Console.WriteLine("ending "); 13:  goto Label1;  14:    } 15:  } 

Output:

 c:\expt>test never ending never ending never ending never ending never ending 

(etc )

The output has been truncated. It carries on printing ' never ' and ' ending ' on alternate lines until you force a termination (by hitting Ctrl-C if running from the command line).



From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net