现在感觉思绪有些混乱。
那个花括号的问题,我主要的目的是想说明:
虽然自动化分析能够分析出一些东西,但是有些信息,如果程序员没有表达出来,那么自动分析是不可能分析出这些信息的。
代码:
{
Integer i = new Integer(1);
Integer j = i;
System.out.println(i);
}
这段代码里,如果一开始i和j就是设计为内部使用的临时变量,那么如果这么写,gc可能也能分析出这一点然后放到栈上。但是就这段代码本身而言,无论是gc还是阅读它的人,都无法搞清楚:这i以后能不能传递到外面去?
现在的事实是,这i没有传到外面,但是原始设计中,这i是否允许传到外面去呢?如果设计不允许,那么最多就只能用拷贝的方法;而如果允许,那么就可以传递引用。但是这段代码里没有描述出这些信息。如果用栈来管理,变成:
代码:
{
Integer i(1);
Integer& j = i;
System.out.println(i);
}
那么这时一眼就能看出来:i是个内部变量,它不应该被(直接按引用)传递到外面。
我又想起一个例子,比如说我经常会使用这样的一段控制代码:
代码:
int main( int argc, char* argv[] )
{
bool running= true;
State state;
while( running ){
switch( state ){
case INIT:
...
break;
case PROC:
...
break;
case FINI:
...
break;
}
}
}
这里的running是在while循环之外的,但是它实际上只是在while循环中起一个控制作用,在while循环外是没有意义的,所以这段代码里,running的事实上的生存期与它应该的生存期是不一致的。所以我现在改成这样:
代码:
for( bool running= true; running; ){
switch(){
...
}
}
这时如果在for循环之外使用running,那么编译会报错。
这段代码因为我用成了习惯,所以不容易把running的作用理解错,可是如果别人不习惯,那么第二种方式既可以描述更强的约束(提供了更多的信息),又可以依靠编译器来实现这种约束。
总之,我希望能尽量把设计信息融入代码,使得代码不仅现在能运作良好,而且能为以后的维护和复用提供更多的信息。