switch 语句中 case 标签后的语句中的重新声明
The redeclaration in a statement after case label inside a switch statement
考虑这个 example
#include <iostream>
int main(){
switch(int a = 1){ //#condition
case 1: switch(int a = 2){}
case 2: switch(int a = 2){}
}
}
为什么 a
的重新声明在这个例子中是合式的?
根据以下规则:
Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement.
IIUC,语句switch(int a = 2){}
或switch(int a = 2){}
中的声明都在受控语句的最外层块中,这是一个复合语句。
对比:
#include <iostream>
int main(){
switch(int a = 1){ //#condition
case 1: int a = 2;
}
}
a
在 case 1
之后的重新声明格式错误,因为它是在该语句的最外层块中重新声明的。
澄清
根据stmt.block,块是复合语句的别名。所以上面的规则完全是关于 block 的,它与范围无关。该规则等同于:
shall not be redeclared in the outermost compound-statement of the controlled statement.
所以,我在这里无法理解的是,由于内部条件 switch
和第一个 switch
的最外层条件之间没有任何块,怎么能说内部 switch
的条件不在外部 switch
?
的最外层块中
switch(int a = 1){ <- outermost block of the primary `switch`
case 1: switch(int a = 2 /*there's no any block contains this condition*/){}
}
对比:
switch(int a = 1){ <- outermost block of the primary `switch`
case 1: { /* here exists a block between `int a = 2` and outermost block of the primary `switch`, so the condition definitely not in the outermost block*/
switch(int a = 2 ){}
}
}
标准中有没有我错过的关于转换的规则,类似于 stmt.while#2,这将使条件包含在发明的块(复合语句)中?
真正的问题是在这里的意思。在 {
和 }
之间分隔 switch
的任何东西当然是 在 那个“最外层块”,但是“最外层”的使用很明显暗示我们不应该考虑(也)嵌套块内的程序部分。达到该解释的最简单方法是将“in”读作“directly in”,与“在命名空间中声明的函数”通常不包含 的成员函数相同。 =31=] 在该名称空间中。然后嵌套 switch
的 condition 被豁免,因为其中的声明不直接在任何块中。
P1787R6 于 2020 年 11 月通过,通过重写 [basic.scope.block] 来明确指代与子语句,独立于 [stmt.while]/2.
中的转换
没有这样的规则。 stmt.while/2 中的代码是误导性的冗余;它同样可以写成
label:
if ( condition ) {
statement
goto label ;
}
有必要看看stmt.pre/5 and basic.scope.block/3中“在”字的意思:
Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement.
这里的“在”是指“马上就在”;它指的是 declaration-statements ,它会影响块的其余部分。通过选择语句的条件进行的声明不在封闭块“中”,它们在该选择语句“中”。
考虑这个 example
#include <iostream>
int main(){
switch(int a = 1){ //#condition
case 1: switch(int a = 2){}
case 2: switch(int a = 2){}
}
}
为什么 a
的重新声明在这个例子中是合式的?
根据以下规则:
Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement.
IIUC,语句switch(int a = 2){}
或switch(int a = 2){}
中的声明都在受控语句的最外层块中,这是一个复合语句。
对比:
#include <iostream>
int main(){
switch(int a = 1){ //#condition
case 1: int a = 2;
}
}
a
在 case 1
之后的重新声明格式错误,因为它是在该语句的最外层块中重新声明的。
澄清
根据stmt.block,块是复合语句的别名。所以上面的规则完全是关于 block 的,它与范围无关。该规则等同于:
shall not be redeclared in the outermost compound-statement of the controlled statement.
所以,我在这里无法理解的是,由于内部条件 switch
和第一个 switch
的最外层条件之间没有任何块,怎么能说内部 switch
的条件不在外部 switch
?
switch(int a = 1){ <- outermost block of the primary `switch`
case 1: switch(int a = 2 /*there's no any block contains this condition*/){}
}
对比:
switch(int a = 1){ <- outermost block of the primary `switch`
case 1: { /* here exists a block between `int a = 2` and outermost block of the primary `switch`, so the condition definitely not in the outermost block*/
switch(int a = 2 ){}
}
}
标准中有没有我错过的关于转换的规则,类似于 stmt.while#2,这将使条件包含在发明的块(复合语句)中?
真正的问题是在这里的意思。在 {
和 }
之间分隔 switch
的任何东西当然是 在 那个“最外层块”,但是“最外层”的使用很明显暗示我们不应该考虑(也)嵌套块内的程序部分。达到该解释的最简单方法是将“in”读作“directly in”,与“在命名空间中声明的函数”通常不包含 的成员函数相同。 =31=] 在该名称空间中。然后嵌套 switch
的 condition 被豁免,因为其中的声明不直接在任何块中。
P1787R6 于 2020 年 11 月通过,通过重写 [basic.scope.block] 来明确指代与子语句,独立于 [stmt.while]/2.
中的转换没有这样的规则。 stmt.while/2 中的代码是误导性的冗余;它同样可以写成
label:
if ( condition ) {
statement
goto label ;
}
有必要看看stmt.pre/5 and basic.scope.block/3中“在”字的意思:
Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement.
这里的“在”是指“马上就在”;它指的是 declaration-statements ,它会影响块的其余部分。通过选择语句的条件进行的声明不在封闭块“中”,它们在该选择语句“中”。