开关箱中的局部作用域
local scope in switch case
我看到了一些令人惊讶的代码:
#include <iostream>
using namespace std;
int main() {
// your code goes here
auto myDummy = [](int i){
switch(i){
case 0: return 0;
case 1:{
std::cout << "Evaluated 1n";
if(i == 1){
return 1;
}
case 2:
std::cout << "Evaluated 2n";
return 2;
}
break;
default: return -1;
}
};
std::cout << myDummy(1) << "n";
return 0;
}
编译并运行时没有警告。大小写1{}的括号似乎被忽略了。
myDummy (1)
-> 1
myDummy (2)
-> 2
如果我将case 1的代码修改为:
case 1:{
std::cout << "Evaluated 1n";
int a = i;
if(a == 1){
return 1;
}
case 2:
std::cout << "Evaluated 2n";
return 2;
}
break;
则不再编译:
prog.cpp:16:13: error: jump to case label [-fpermissive]
case 2: ^ prog.cpp:12:21: note: crosses initialization of 'int a' int a = i;
第1种情况的括号:{}break;不要取消交换机上下文。它只是为变量创建了一个局部作用域。但这真的很令人困惑。为什么会有这样的行为?
以下是标准对switch
(§6.4.2,重点是我的)的描述:
2 - 表中的任何语句开关语句可以用一个或多个case标签标记为如下:情况下常数表达式:在哪里常数表达式须为转换后的常数表达式(5.19)的提升型开关状态。
& lt;…>
5 -当开关语句执行时,计算其条件并与每个case常量进行比较。如果其中一个case常量等于条件的值,控制传递给后面的语句匹配的case标号
所以switch
不关心具体的情况,下面的工作:
int main() {
int i = 0;
switch(i)
{
case 1:
{
case 2:
{
if(false)
{
case 0:
std::cout << "hello there!"; //yes it will print
}
}
}
}
return 0;
}
关于你提出的修改,请检查我对这个问题的回答。基本上是用
case 1:{
std::cout << "Evaluated 1n";
int a = i;
if(a == 1){
return 1;
}
case 2:
//here a is in scope
std::cout << "Evaluated 2n";
return 2;
}
您可以跳转到case2
而不实际创建a
,但a
仍将在范围内。
switch
到标签的工作方式与goto
与标签的工作方式相同,当涉及到移动到不同的作用域块时
在采用这种方案时应该小心,特别是在读取未初始化的变量时,它的行为是未定义的。
你可以在任何地方设置作用域:
int main() {
int a;
{
int a; // in a more local scope.
}
}
但是你不能把一个变量初始化放在一个作用域中,它会被超过2次的切换可见:
int main() {
int b;
switch(1) {
case 0:
int a = 0; // error
break;
case 1:
b = a; // what happens?
break;
}
}
最后,在另一个作用域内使用case标签没有问题(只要它不违反我们的第二条规则):
int main() {
switch(1) {
case 1: {
break;
case 2:
break;
}
}
}
相关文章:
- 未在作用域中声明unordered_map
- 有没有一种方法可以在编译时获得作用域类名
- C++quit()函数中可能存在作用域问题
- 未在此作用域OpenCV3.4中声明cvSaveImage
- 全局作用域中函数指针的赋值
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 局部变量的作用域是块或函数
- 作用域和线程局部变量如何在 (V8) C++中工作?
- 开关箱中的局部作用域
- 在c++中是否有办法访问外部作用域中的局部变量?
- 将.txt文件中的字符串输出到成员方法局部作用域之外的动态数组
- 局部作用域和函数作用域的区别
- 线程局部全局作用域变量
- c++局部作用域减少内存
- 局部变量在超出作用域时删除另一个变量的内存
- c/c++中局部变量作用域和生命周期的混淆
- c++中的局部/静态变量作用域
- 从函数返回一个局部声明的指针是否会导致它切换作用域?
- rand() + rand()具有局部作用域