先上代码
static int arr[4] = {1, 2, 3, 4};
void func2(int v, int nv) {
int n = 0;
while (n < 4 && arr[n] != v)
n++;
if(n < 4)
arr[n] = nv;
}
void func3(int v, int nv) {
int n = 0;
while (arr[n] != v && n < 4)
n++;
if(n < 4)
arr[n] = nv;
}
测试结果
无论是在linux 下编译还是在windows 下使用gcc 在-O2/-Os 级别下编译都会出现:
func2 不会 出现n >= 4 的情况
func3 会出现 n >= 4 的情况
问题分析
通过分析汇编 func3 函数 在 -O2/-Os
级别的中编译会将 && n < 4 和 if(n < 4) 这两个判断给优化掉(没有cmp R0, 4 这句汇编)
导致问题
由于有 if(n < 4)
这个判断,我们会认为,怎么的这n 也不会超过 4 ,从而进行读写操作,进而可能引发灾难的后果!!!
推测原因
编译器认为:既然会第一个判断arr[n] != v,那么就有可能会越界访问(arr数组长度就是4),如果是正确的代码,那么就是写代码时就会控制不会溢出访问,那么就没有第一个 n < 4 判断就没有必要,既然n 不会超过或者等于4,那么if(n < 4) 也没有必要存在。