由于一个小错别字,我偶然发现了这个结构:
int main(void) {
char foo = 'c';
switch(foo)
{
printf("Cant Touch This\n"); // This line is Unreachable
case 'a': printf("A\n"); break;
case 'b': printf("B\n"); break;
case 'c': printf("C\n"); break;
case 'd': printf("D\n"); break;
}
return 0;
}
看起来switch语句顶部的printf是有效的,但也完全不可访问。
我得到了一个干净的编译,甚至没有关于不可达代码的警告,但这似乎毫无意义。
编译器应该将此标记为不可访问的代码吗?
这有什么用吗?
这有什么用吗?
是的。如果你在第一个标签之前放一个声明而不是语句,这是完全有意义的:
switch (a) {
int i;
case 0:
i = f(); g(); h(i);
break;
case 1:
i = g(); f(); h(i);
break;
}
声明和语句的规则在一般情况下对于块是共享的,所以同样的规则也允许那里的语句。
值得一提的是,如果第一个语句是一个循环结构,case标签可能会出现在循环体中:
switch (i) {
for (;;) {
f();
case 1:
g();
case 2:
if (h()) break;
}
}
如果有更可读的方式,请不要编写这样的代码,但这是完全有效的,而且f()调用是可达的。
也许不是最有用的,但也不是完全没有价值。你可以用它来声明一个在开关范围内可用的局部变量。
switch (foo)
{
int i;
case 0:
i = 0;
//....
case 1:
i = 1;
//....
}
标准(N1579 6.8.4.2/7)有以下示例:
在人工程序片段中
开关(expr)
{
Int I = 4;
f(我);
例0:
I = 17;
/*变为默认代码*/
默认值:
printf (" % d \ n”,我);
}
标识符为I的对象存在并具有自动存储持续时间(在块内),但从不存在
初始化,因此如果控制表达式具有非零值,则对printf函数的调用将
访问一个不确定的值。类似地,无法到达对函数f的调用。
P.S. BTW,样例不是有效的c++代码。在这种情况下(N4140 6.7/3,我的重点):
A program that jumps90 from a point where a variable with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default
constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the
preceding types and is declared without an initializer (8.5).
90) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
替换int i = 4;用int i;使它成为一个有效的c++。