4

灵感来自这个问题的答案
是 C# 中 switch 的空情况与下一个非空情况相结合吗?

该术语的唯一出现出现在 C# 语言规范的 §6.5 中

  • 如果D有一个非空返回类型并且主体F是一个语句块,当每个参数F被赋予相应参数的类型时D,主体F是一个有效的语句块(wrt §8.2),具有不可到达的结束每个 return 语句指定一个表达式的D,该表达式可隐式转换为 的返回类型。

在规范的后面我们可以看到

  • 8.1 端点和可达性

    每个语句都有一个终点。直观地说,语句的结束点是紧接在语句之后的位置。复合语句(包含嵌入语句的语句)的执行规则指定当控制到达嵌入语句的终点时所采取的动作。例如,当控制到达块中语句的终点时,控制将转移到块中的下一条语句。
    ...

我们可能对此有所了解。但是,我搜索了一下,发现没有直接解释non-reachable endpoint。因为 Stack Overflow 是一个问答网站,我认为如果有一个更简单、更直观的解释,可以很容易地搜索和理解这个术语,对程序员尤其是非英语母语的程序员会有帮助。

4

2 回答 2

2

本的回答很好地说明了这一点。更准确地说,端点:

  • 休息
  • 继续
  • 返回

语句不可访问。这些语句中的每一个都在“结束之前”将控制权转移到其他地方,因此语句的“结束点”永远不会被击中。将其与以下语句进行比较:

  • Console.WriteLine();
  • 我++;

依此类推,将控制权转移到下一条语句。

循环提出了一个有趣的挑战:

while(x) { M(); }

这基本上与以下内容相同:

BEGIN: 
if (!x) goto END;
{ M(); }
goto BEGIN;
END: ;

所以端点是可达的。但

while(true) { M(); }

可以优化为:

BEGIN: 
{ M(); }
goto BEGIN;

由于现在没有办法“走到尽头”,所以这条语句被认为有一个无法到达的终点。这要么永远循环,要么 M() 永远不会返回,或者 M() 抛出;无论哪种方式,都不会到达语句的终点。

确定可达性的确切规则比这个草图要复杂一些,但这让你对它们有所了解。(我想给人们一个挑战,看看他们是否掌握了可达性:编写一个程序,它有一个可达的 goto 语句,但相应的标记语句是不可达的。棘手!)

这些规则用于许多地方。立即想到的三个:首先,开关部分不能有可到达的端点。其次,非 void 的方法(或 lambda 或属性 getter 等)不得具有可到达的端点。第三,如果一个方法有一个可到达的端点并且它有一个out参数,那么这个参数必须明确地分配在端点。

于 2013-03-01T23:34:32.703 回答
0

简而言之,当且仅当语句在没有执行分支的情况下完成(控制转移)时才到达端点。

因此,当退出块的分支是

  1. 无条件的,或
  2. 存在于所有可能的执行路径中。
于 2013-03-01T23:04:31.223 回答