自我总结:(之前查过goto和switch的资料但是一直没有搞懂,直到今天看到这个讨论才懂了)
1 int a; 是个描述,而不是个命令,只是说明我需要空间,编译器会保证在相应的作用域之中这个变量的空间是被分配了(只要改一下堆栈指针就好)。
2 大部分编译期实现会选择在函数开始把所有局部变量的空间都分配好。
3 声明还可以是一个类的对象,那么这时候这个声明的语句就很可能是一个命令了:调用相应的构造函数。这种情况下,编译器就会告诉你跳过了该做的事情,不能这么写了。
原问题:http://www.zhihu.com/question/23051685
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 bool b = false; 7 8 switch (false) 9 { 10 case true: 11 int ival; 12 break; 13 14 case false: 15 ival = 3; 16 cout << ival << endl; 17 } 18 19 return 0; 20 }
这段c++代码应该直接执行switch语句中的 case false,这样的话ival应该没有被定义,为什么程序能被编译通过,并顺利执行?(编译器gcc4.7)
这边的ival应该是局部变量,应该运行时在栈上分配空间啊,那么应该不存在在编译时已经分配好空间的问题了吧?
回答:
---------------------------------------------------------------------------
vczh,专业造轮子 http://www.gaclib.net
不能跳过的不是变量的定义,而是初始化。你把int ival改成int ival=0;或者string ival,你就可以看到效果。
----------------------------------------------------------------------------
pansz,自由软件开发者
ival是局部变量,作用域是所在的大括号内。
所以第二个case仍然属于该变量的作用域。
另外,变量的定义不是语句,所以无需执行也是全范围有效。这里第一个case的语句虽然没有被执行,但它的变量定义仍然有效。
同vczh说的一样,能跳过的是变量初始化而不是变量定义。变量无论在何处定义都有效,switch只能跳过变量初始化,不能跳过变量定义。
----------------------------------------------------------------------------
刘城,不要上zhihu了!
你的理解有一些误区,变量的声明和定义的作用是在静态域,与是否执行到没有关系。定义变量并不存在执行动作。
为什么这个容易误解呢,因为c语言switch语句设计的比较悲剧,每个case部分是没有独立的作用域的。要理解它,一种方法是把它当作goto来看。 比如这个程序就是:
1 #include <iostream> 2 using namespace std; 3 int main() { 4 bool b = false; 5 goto case_false; 6 case_true: 7 int ival; 8 goto switch_end; 9 case_false: 10 ival = 3; 11 cout << ival << endl; 12 switch_end: 13 return 0; 14 }
再说一下动态分配的事情,先说清楚分配不是有一条指令教int xxx,执行到这里的时候会分配空间,这个是个描述,而不是个命令,只是说明我需要空间,编译器会保证在相应的作用域之中这个变量的空间是被分配了。
大部分编译期实现会选择在函数开始把所有局部变量的空间都分配好(只要改一下堆栈指针就好)。
最后补充一下,你的声明还可以是一个类的对象,那么这时候这个声明的语句就很可能是一个命令了:调用相应的构造函数。这种情况下,编译器就会告诉你跳过了该做的事情,不能这么写了。