"Недостижимые" метки в комбинации goto и try-finally - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Стандарт языка ECMA-334 описывает одну интересную особенность работы перехода по меткам goto: если оператор goto, находящийся в блоке try, указывает на метку, находящуюся вне блока try-catch-finally, то при переходе по метке будут вызваны все блоки finally, относящиеся к этому блоку try
... A goto statement is executed as follows:
  • If the goto statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all intervening try statements have been executed.
  • Control is transferred to the target of the goto statement.
Because a goto statement unconditionally transfers control elsewhere, the end point of a goto statement is never reachable.
И код, описывающий эту ситуацию, работает без замечаний
using System;
 
namespace ConsoleApp
{
    class MainClass
    {
        public static void Main(string[] args) {
            try {
                goto outLabel;
            }
            catch {
                Console.WriteLine("catch executed.");
            }
            finally {
                Console.WriteLine("finally executed.");
            }
            outLabel: Console.WriteLine("out of try-finally block.");
        }
    }
}
finally executed.
out of try-finally block.
Однако, если добавить обработку исключения, то компилятор заметит, что метка является недостижимой, однако таковой она не является
using System;
 
namespace ConsoleApp
{
    class MainClass
    {
        public static void Main(string[] args) {
            try {
                throw new NullReferenceException();
                goto outLabel;
            }
            catch {
                Console.WriteLine("catch executed.");
            }
            finally {
                Console.WriteLine("finally executed.");
            }
            outLabel: Console.WriteLine("out of try-finally block.");
        }
    }
}
catch executed.
finally executed.
out of try-finally block.
Компилятор Mono 4.2.1.0 сделает два замечания
Program.cs(10,5): warning CS0162: Unreachable code detected Program.cs(18,4): warning CS0164: This label has not been referenced
Майкрософтовский компилятор (4.0) сделает только одно (первое из них). Почему компиляторы генерируют такие warning'и?

Решение задачи: «"Недостижимые" метки в комбинации goto и try-finally»

textual
Листинг программы
outLabel: Console.WriteLine("out of try-finally block.");

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4 из 5