什么编译器考虑switch语句?

Ken*_*Kin 16 c# switch-statement unreachable-code

从一个-5问题再次启发!

我读了@Quartermeister的 [ 评论 ] 并感到惊讶!

那么为什么这会编译

switch(1) {
    case 2:
}
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.

int i;

switch(i=1) {
    case 2: // Control cannot fall through from one case label ('case 2:') to another
}
Run Code Online (Sandbox Code Playgroud)

这不是

switch(2) {
    case 2: // Control cannot fall through from one case label ('case 2:') to another
}
Run Code Online (Sandbox Code Playgroud)

更新:

-5问题变得-3.

Eri*_*ert 21

他们都不应该编译.C#规范要求switch部分至少有一个语句.解析器应该禁止它.

让我们忽略解析器允许空语句列表的事实; 这不是什么相关的.规范说开关部分的末端必须没有可达到的终点; 这是相关的一点.

在上一个示例中,交换机部分具有可到达的终点:

void M(int x) { switch(2) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

所以一定是个错误.

如果你有:

void M(int x) { switch(x) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

然后编译器不知道x是否会是2.它保守地假定它可以,并且说该部分具有可到达的终点,因为交换机案例标签是可达的.

如果你有

void M(int x) { switch(1) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

然后,编译器可以推断端点不可访问,因为无法访问案例标签.编译器知道常量1永远不会等于常量2.

如果你有:

void M(int x) { switch(x = 1) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

要么

void M(int x) { x = 1; switch(x) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

然后你知道并且我知道终点是不可达的,但编译器不知道这一点.规范中的规则是可达性仅通过分析常量表达式来确定.包含变量的任何表达式,即使您通过其他方式知道其值,也不是常量表达式.

在过去,C#编译器存在错误,而事实并非如此.你可以这样说:

void M(int x) { switch(x * 0) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

并且编译器会推断x*0必须为0,因此无法访问case标签.这是一个bug,我在C#3.0中修复过.规范说只有常量用于该分析,并且x是变量,而不是常量.

现在,如果程序是合法的,那么编译器可以使用这样的高级技术来影响生成的代码.如果你说的话:

void M(int x) { if (x * 0 == 0) Y(); }
Run Code Online (Sandbox Code Playgroud)

然后编译器可以生成代码,就像您编写的那样

void M(int x) { Y(); }
Run Code Online (Sandbox Code Playgroud)

如果它想要的话.但它不能使用x * 0 == 0确定语句可达性的事实.

最后,如果你有

void M(int x) { if (false) switch(x) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

然后我们知道交换机是不可达的,因此该块没有可达到的终点,所以这令人惊讶地是合法的.但鉴于上面的讨论,你现在知道了

void M(int x) { if (x * 0 != 0) switch(x) { case 2: ; } }
Run Code Online (Sandbox Code Playgroud)

x * 0 != 0视为false,因此终点被认为是可达的.