gcc优化会影响边界检查

时间:2011-07-13 15:11:16

标签: gcc compiler-warnings compiler-optimization

考虑以下示例:

int a[4];

int main() {
  a[4] = 12; // <--
  return 0;
}

这显然是一个出界错误,不是吗?我想知道gcc什么时候会对此发出警告,并发现只有在优化为-O2或更高时它才会这样做(这受-ftree-vrp选项的影响,该选项仅为{{1}自动设置} 或更高)。 我真的不明白为什么这是有道理的,否则gcc不会发出警告是否正确。

文档说明了这个问题:

  

这允许优化器删除不必要的范围检查,如数组绑定检查和空指针检查。

不过,我不明白为什么不需要检查?

1 个答案:

答案 0 :(得分:1)

您的示例是常量传播的情况,而不是值范围传播,它肯定会在我的gcc版本(4.5.1)上触发警告,无论是否-ftree-vrp已启用。

通常,Java和Fortran是gcc支持的唯一语言(默认情况下为Java,如果您明确要求使用-fbounds-check,则为Fortan)将生成用于检查数组边界的代码。

但是,虽然C / C ++不支持任何此类事情,但如果编译器认为某些内容不对,编译器仍会在编译时警告。对于常数,这是非常明显的,对于可变范围,它有点难度。

子句“允许编译器删除不必要的范围检查”涉及例如使用无符号8位宽变量索引到具有> 256个条目的数组或无符号16位值以索引到数组> 65536个元素。或者,如果你在一个循环中迭代一个数组,并且(变量)循环计数器是 bounded 的值可以被证明为合法数组索引的编译时常量,所以计数器永远不会可能超出阵列界限 在这种情况下,编译器既不警告您也不为支持此目标语言生成任何代码。