简介
近期在研究组的项目中,继续开发师兄写的SDK时发现一个小trick,即在判断语句中利用编译器自身对判断语句的优化,使用前面条件的结果规避了后面条件的执行错误,详情描述如下。
trick的发现
以下为师兄所写源码的伪代码(基于C#)
if(foo(ref a) && a.get()) // ref在C#表示传引用值(函数传参可分为传值和传引用,具体请自行搜索)
return false;
else
return true;
由于我在调试时想查看foo(ref a)执行后a对象中的值,因此将以上代码临时修改成如下格式
bool res1 = foo(ref a);
bool res2 = a.get();
if(a && b)
return false;
else
return true;
但执行后a.get()语句报空指针错误。
逻辑相同的代码,在从if中将两个语句提出来后就报错了,郁闷。
忽然想起来之前看过的一篇文章讲过编译器的优化:在判断语句已经能够根据前面的结果做出最终决定时,将不再对后续条件进行判断,以减少资源的占用和加快程序的运行速度。
因此,原版的代码中由于foo函数返回值为false(此时a也为null),所以a.get()语句并未执行,也就不会产生空指针的错误。
补充
- 如果希望判断语句中的所有语句都得到执行,可以不使用逻辑运算符&&、||,而是使用&和|这两个算数运算符。由于判断语句需要对&和|的最终计算结果进行判断,因此不会提前终止括号内的语句执行。
- 个人认为虽然trick优秀,但考虑到代码的可读性和健壮性,还是应该对语句可能存在的错误进行检查(仁者见仁智者见智)
网友评论