4

Here's Eric Lippert's comment from this post:

Now that you know the answer, you can solve this puzzle: write me a program in which there is a reachable goto which goes to an unreachable label. – Eric Lippert Jul 17 at 7:17

I am not able to create a code which will have reachable goto pointing to an unreachable label. Is that even possible? If yes, what would the C# code look like?

Note: Let's not get into discussion about how 'goto' is bad etc. This is a theoretical exercise.

Community
  • 1
  • 1
SolutionYogi
  • 31,807
  • 12
  • 70
  • 78

3 Answers3

13

My original answer:

    try
    {
        goto ILikeCheese;
    }
    finally
    {
        throw new InvalidOperationException("You only have cottage cheese.");
    }
ILikeCheese:
    Console.WriteLine("MMM. Cheese is yummy.");

Here is without the compiler warning.

    bool jumping = false;
    try
    {
        if (DateTime.Now < DateTime.MaxValue)
        {
            jumping = (Environment.NewLine != "\t");
            goto ILikeCheese;
        }

        return;
    }
    finally
    {
        if (jumping)
            throw new InvalidOperationException("You only have cottage cheese.");
    }
ILikeCheese:
    Console.WriteLine("MMM. Cheese is yummy.");
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • 1
    Wrong. The documentation for goto says that when it is in a try-finally block, the finally will still be executed. – Will Eddins Jul 22 '09 at 19:40
  • For the above code, compiler gives me warning that 'unreachable code' detected. I was thinking about an example where compiler won't be able to detect that the label is unreachable. At least that's what I was thinking about when Eric posted that comment. – SolutionYogi Jul 22 '09 at 19:44
  • 1
    I thought the question was the goto needs to reach an unreachable label. In this case, an exception will be thrown by the finally, crashing it before it reaches the label. – Will Eddins Jul 22 '09 at 19:45
  • 2
    Yeah this is a bit like the "chicken and the egg", if a reachable `goto` can go to an unreachable label, doesn't that make the label reachable? – John Rasch Jul 22 '09 at 19:49
  • @Guard: If it's reachable, then it's not unreachable. Are we instead looking for code the compiler thinks is unreachable, but really is? If so, then by definition the only way would be with unsafe code. – Sam Harwell Jul 22 '09 at 19:53
  • This looks reasonable to me though I am not sure if this is the kind of code Eric had in mind. Let's see if he will look at this question. – SolutionYogi Jul 22 '09 at 19:58
  • +1. I would also throw an exception is cottage cheese were my only choice. – Erich Mirabal Jul 22 '09 at 20:04
  • @Guard that depends on the value of Environment.NewLine (I know off no platform where the value would be \t tho :) ) – Rune FS Jul 22 '09 at 20:12
  • According to the language, that label is obviously reachable (the language definition doesn't know the semantics of every method in the BCL), so I suspect Mr Lippert had something else in mind (maybe a compiler bug in the present version?) – Daniel Earwicker Jul 22 '09 at 20:44
  • 4
    Congratulations, that is the answer I had in mind. The goto is reachable but the label it targets is not because the "finally" hijacks it. The code in the compiler which detects that case is arcane, to say the least. – Eric Lippert Jul 22 '09 at 22:28
  • Thanks 280Z28! What does your 'id' mean? Can we use a pronounceable id? :) – SolutionYogi Jul 23 '09 at 01:08
  • It's "Two eighty Z twenty eight." I have a '78 280Z with a Camaro Z28's engine: http://www.280z28.org/images/z/IMG_2020.jpg – Sam Harwell Jul 23 '09 at 01:12
  • Wow. The car doesn't look like it's 31 years old! Awesome. – SolutionYogi Jul 23 '09 at 01:14
0

By the way if you use goto the csharp compiler for example for this case without finally block changes the code to a version without goto.

using System;
public class InternalTesting
{
public static void Main(string[] args)
{
  bool jumping = false;
    try
    {
        if (DateTime.Now < DateTime.MaxValue)
        {
            jumping = (Environment.NewLine != "\t");
            goto ILikeCheese;
        }
    else{
            return;
    }
    }
    finally
    {
        if (jumping)
{
            //throw new InvalidOperationException("You only have cottage cheese.");
    Console.WriteLine("Test Me Deeply");
}
    }
ILikeCheese:
    Console.WriteLine("MMM. Cheese is yummy.");
}
}

Turns To:

public static void Main(string[] args)
{
    bool flag = false;
    try
    {
        if (DateTime.Now < DateTime.MaxValue)
        {
            flag = Environment.NewLine != "\t";
        }
        else
        {
            return;
        }
    }
    finally
    {
        if (flag)
        {
            Console.WriteLine("Test Me Deeply");
        }
    }
    Console.WriteLine("MMM. Cheese is yummy.");
}
Pascal Paradis
  • 4,275
  • 5
  • 37
  • 50
Kerem Kusmezer
  • 492
  • 7
  • 15
-1
goto cant_reach_me;

try{
cant_reach_me:
}
catch{}

This is either a compile or runtime error, I can not remember. The label must be outside the try/catch block

MadHak
  • 1