gcc优化影响边界检查

gcc优化影响边界检查,gcc,compiler-warnings,compiler-optimization,Gcc,Compiler Warnings,Compiler Optimization,考虑以下示例: int a[4]; int main() { a[4] = 12; // <-- return 0; } inta[4]; int main(){ a[4]=12;//您的示例是常数传播,而不是值范围传播,无论是否启用了-ftree vrp,它都会在我的gcc版本(4.5.1)上触发警告 一般来说,Java和Fortran是gcc支持的唯一语言(默认情况下,Java和Fortan(如果您使用-fbounds check)明确要求),将生成用于检查数组边界的代码

考虑以下示例:

int a[4];

int main() {
  a[4] = 12; // <--
  return 0;
}
inta[4];
int main(){
a[4]=12;//您的示例是常数传播,而不是值范围传播,无论是否启用了
-ftree vrp
,它都会在我的gcc版本(4.5.1)上触发警告

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

然而,尽管C/C++不支持任何这样的东西,编译器仍然会在编译时警告您,如果它认为有什么问题。对于常量,这是非常明显的,对于变量范围,这有点困难

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

您的示例是持续传播,而不是值范围传播,并且无论是否启用了
-ftree vrp
,它肯定会在我的gcc版本(4.5.1)上触发警告

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

然而,尽管C/C++不支持任何这样的东西,编译器仍然会在编译时警告您,如果它认为有什么问题。对于常量,这是非常明显的,对于变量范围,这有点困难

子句“允许编译器删除不必要的范围检查”与以下情况有关:例如,您使用一个8位宽的无符号变量索引到一个大于256个条目的数组中,或使用一个16位无符号值索引到一个大于65536个元素的数组中。或者,如果您在循环中迭代一个数组,则使用(变量)循环计数器由可证明为编译时常量的值(合法数组索引)所限定,因此计数器永远不可能超出数组界限。

在这种情况下,编译器既不会警告您,也不会为受支持的目标语言生成任何代码。

因此,如果您使用
gcc-O0-Wall main.c
it(
gcc 4.4.3
)编译我的示例代码向您发出警告?因为它在我的机器上肯定不会。但是,如果我说的是
-O2
而不是
-O0
,它会发出警告。我用
-O2
-O3
编译了它,有
-Wall
和没有,有
-fbounds check
和没有。每次都收到警告(gcc 4.5.1).准确地说,正如我所说,您总是会收到带有
-O2
和更高级别的警告(即
-O3
-Os
)但是,你不能使用
-O1
-O0
。原因是
-ftree vrp
是由
-O2
-O3
-Os
暗示的。问题是为什么?--如果你能用
-O0
再次尝试,那就太好了。没错,它会用
-O2
和highe>发出警告r、 或者手动使用
-ftree vrp
选项进行任何优化(包括
-O1
-Os
)(我在IDE的全局设置中没有注意到这一点,所以即使
-O1
也会发出警告)。这也与显式
-Warray边界
无关。尽管后者的文档中说(无需进一步解释)它只能在
-ftree vrp
处于活动状态时工作。我假设原因是警告启发式使用优化器树,如果根本没有进行优化,优化器树就不存在。因此,如果您使用
gcc-O0-Wall main.c
it(
gcc 4.4.3
)编译我的示例代码向您发出警告?因为它在我的机器上肯定不会。但是,如果我说的是
-O2
而不是
-O0
,它会发出警告。我用
-O2
-O3
编译了它,有
-Wall
和没有,有
-fbounds check
和没有。每次都收到警告(gcc 4.5.1).准确地说,正如我所说,您总是会收到带有
-O2
和更高级别的警告(即
-O3
-Os
)但是,你不能使用
-O1
-O0
。原因是
-ftree vrp
是由
-O2
-O3
-Os
暗示的。问题是为什么?--如果你能用
-O0
再次尝试,那就太好了。没错,它会用
-O2
和highe>发出警告r、 或者手动使用
-ftree vrp
选项进行任何优化(包括
-O1
-Os
)(我在IDE的全局设置中没有注意到这一点,所以即使
-O1
也会发出警告)。这也与显式
-Warray边界
无关。尽管后者的文档中说(无需进一步解释)它只能在
-ftree vrp
处于活动状态时工作。我假设原因是警告启发式使用优化器树,如果根本没有进行优化,优化器树就不存在。是否对下一票进行评论?是否对下一票进行评论?