tags:

views:

541

answers:

3

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.

+10  A: 

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.");
280Z28
Wrong. The documentation for goto says that when it is in a try-finally block, the finally will still be executed.
Will Eddins
@Guard: Isn't that the point?
280Z28
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
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
Although the logic of the two combined are now giving me a headache...
Will Eddins
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
@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.
280Z28
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
+1. I would also throw an exception is cottage cheese were my only choice.
Erich Mirabal
@Guard that depends on the value of Environment.NewLine (I know off no platform where the value would be \t tho :) )
Rune FS
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
@Earwicker, check my edit. I brought back both versions.
280Z28
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
Thanks 280Z28! What does your 'id' mean? Can we use a pronounceable id? :)
SolutionYogi
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
280Z28
Wow. The car doesn't look like it's 31 years old! Awesome.
SolutionYogi
+1 because Eric Lippert says it's right.
Michael Myers
A: 

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.");
}
Kerem Kusmezer
A: 
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