为什么抛出两种例外连胜不会产生无法访问的代码警告?为什么抛出两种例外连胜不会产生无法访问的代码警告?

2019-05-11 21:26发布

为什么下面的代码行不能创建一个编译器警告?

void Main()
{
  throw new Exception();
  throw new Exception();
}

在我看来,编译器应该告诉你的是,第二抛出异常无法达成。

Answer 1:

这显然是一个编译器缺陷,它被引入C#3.0 - 对周围我重构严重的可达性检查的时间。 这大概是我不好,对不起。

该缺陷是完全良性的; 基本上,我们只是忘了在警告记者的情况。 我们正确地生成的可达性信息; 正如其他人所指出的,我们正确地修剪出的代码生成之前无法访问的代码。

该错误无非是在警告发生器遗漏的情况多。 我们有一些棘手的代码在那里,确保我们当你的代码无法访问一些大节不报是数不胜数警告。 编译器有代码无条件的goto(“转到”,“破发”,“继续”),有条件的goto特别报告警告(“如果”,“而”等),的try-catch-finally程序(包括等价形式到的try-catch-最后,如锁和使用),块,返回(回收率和定期返程),局部声明,标号语句,开关和表达语句。

你看到的是名单上的“throw语句”? 我也不。 这是因为我们忘记它。

不便之处敬请原谅。 我会发一张纸条给QA,我们会尽快为这个修复到语言的未来版本。

感谢您将这一引起我的注意。



Answer 2:

它会给人一种编译器警告/错误,但遗憾的是它没有。 但是,如果你看看IL代码只第一异常重视。 您可以登录到connect.microsoft.com,提高本的东西,你想看到的。

如果你ILDASM下面的代码

static void Main(string[] args)
        {
            Console.Write("Line 1");
           throw new Exception(); 
           throw new Exception();
           Console.Write("Line 4");
        }

您将获得本

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       18 (0x12)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Line 1"
  IL_0006:  call       void [mscorlib]System.Console::Write(string)
  IL_000b:  nop
  IL_000c:  newobj     instance void [mscorlib]System.Exception::.ctor()
  IL_0011:  throw
} // end of method Program::Main

后的第一个异常对象没有别的转换为IL。



Answer 3:

此错误(如利珀特称之为以上)有一些奇怪的后果。 当然,这样的代码也没有给出编译时警告:

static int Main()
{
  return 0;

  throw new Exception("Can you reach me?");
}

如果你是有创意,你仍然可以使throw声明诱导(无关)的警告。 在这种奇怪的例子中,代码生成,只是因为“绿色”不可达的警告:

static int Main()
{
  return 0;

  throw new Exception(((Func<string>)(() => { if (2 == 2) { return "yellow"; } return "green"; }))());
}

(代码只是从拉姆达创建委托实例并调用代表)。

但这个例子比较简单,似乎更糟糕:

static int Main()
{
  int neverAssigned;

  return 0;

  throw new Exception(neverAssigned.ToString());
}

这最后的代码示例还编译没有警告! 有一个在“使用”没有问题neverAssigned因为“使用”不可达。 但你也没有得到关于一个局部变量从未分配给(和从来没有“真正”读)的警告。 如此重复,没有警告可言,这似乎是非常错误的。

我不知道这种行为将在Visual C#中的未来版本是否会改变? 改变它会给人警告他们以前是没有的(这在我看来他们应得的)。

另外:此行为似乎与不变罗斯林为基础的的Visual Studio 2015年的C#6.0编译。



文章来源: Why does throwing 2 exceptions in a row not generate an unreachable code warning?