在http://blog.csdn.net/wuhui_gdnt/article/details/8755973上,我看到这样一个例子:
1 void contains_null_check(int *P) { 2 int dead = *P; 3 if (P == NULL) 4 return; 5 *P = 4; 6 }
假设开启了“重复空指针检查消除(Redundant NullCheck Elimination)”和“死代码消除(DeadCode Elimination)”。
情况一:先消除死代码
void contains_null_check_after_DCE(int *P) { //int dead = *P; // deleted by the optimizer. if (P == 0) return; *P = 4; }
在上面的例子中,由于int dead 并没有什么卵用,因此被编译器优化掉了。
然后,编译器分析这一句:
void contains_null_check_after_DCE_and_RNCE(int *P) { if (P == 0) // Null check not redundant, and is kept. return; *P = 4; }
结束。
情况二:编译器先运行重复空指针检查消除。
void contains_null_check_after_RNCE(int *P) { int dead = *P; if (false) // P was dereferenced by this point, so it can't be null return; *P = 4; }
编译器想:因为P在之前解引用了,因此P一定不是空指针,所以P == 0永远是假的。
然后,运行死代码消除:
void contains_null_check_after_RNCE_and_DCE(int *P) { //int dead = *P; //if (false) // return; *P = 4; }
也就是说,上面的代码被“优化”成了一个不进行空指针检查的语句。
另外编译器在优化时似乎不考虑溢出的情况,比如自作聪明的if(i + 1 > i) i++;可能达不到防止溢出的效果:i + 1 > i被优化成了true,然后就不对i进行检查了。