C++ 为什么不是';即使被请求,gcc也不会抱怨数组边界?

C++ 为什么不是';即使被请求,gcc也不会抱怨数组边界?,c++,g++,compiler-warnings,C++,G++,Compiler Warnings,我正在使用GCC4.9.0,我希望看到编译器警告我超出了数组边界。如果我编译这个 int main() { int table[5]={0}; table[8] = 1234; int x = table[10]; } 使用g++-O2-Wall main.cpp-o main.exe,我只会收到关于未使用x的警告: main.cpp: In function 'int main()': main.cpp:8:7: warning: unused variable 'x

我正在使用GCC4.9.0,我希望看到编译器警告我超出了数组边界。如果我编译这个

int main()
{
    int table[5]={0};
    table[8] = 1234;
    int x = table[10];
}
使用g++-O2-Wall main.cpp-o main.exe,我只会收到关于未使用x的警告:

main.cpp: In function 'int main()':
main.cpp:8:7: warning: unused variable 'x' [-Wunused-variable]
int x = table[10];
   ^
从gcc文档()中,我看到-O2和-Wall应该一起启用-Warray bounds=1检查。如果我尝试添加-Warray边界,事情不会改变。事实上,编译器甚至无法识别-Warray bounds=1:

g++: error: unrecognized command line option '-Warray-bounds=1'

现在,为什么编译器不给出任何关于错误写入/读取数组的警告?为什么编译器不能识别'-Warray bounds=1'?

编译器可能会对其进行优化。尝试使
表格
易失性

int main()
{
    volatile int table[]={0,0};
    table[8] = 1234;
    int x = table[10];
}
产生:

prog.cc:4:12: warning: array subscript is above array bounds [-Warray-bounds]
     table[8] = 1234;
     ~~~~~~~^
prog.cc:5:21: warning: array subscript is above array bounds [-Warray-bounds]
     int x = table[10];
             ~~~~~~~~^
这是一个例子


-Warray bounds
文档:

它警告数组的下标总是超出范围

我的猜测是,当访问从未真正发生时,g++决定不发出警告


事实上,编译器甚至无法识别-Warray bounds=1:

g++: error: unrecognized command line option '-Warray-bounds=1'
g++:错误:无法识别的命令行选项'-Warray bounds=1'


g++-4.9.0不支持格式为
-Warray-bounds=n
的命令,但它在
-Warray-bounds
中可以正常工作
-Warray bounds=n
受g++-5.1.0支持。

我怀疑缺少警告是因为优化。编译器很容易看到,您编写的任何一行都不会对程序的行为产生任何影响,因此可能会选择跳过这些行

检查编译时已知的越界访问的阶段似乎是在删除未使用的代码之后执行的,因此GCC从未看到您的错误


防止这种优化的一个简单方法是声明数组
volatile
。编译器必须将对
volatile
对象的任何写入或读取视为副作用,因此无法进行优化。

clang仍然会发出警告,无论优化如何。无论优化如何,gcc都不会对此发出警告:请注意,您链接到的文档是针对最新版本的gcc的,因此它可能与4.9版本的文档有所不同。您不会使用
=1
=0
-W
选项。只有
-Wsome warning
-Wno一些警告
。代码仍在编译中,因此奇怪的是优化会使警告不显示。无论优化级别如何,Clang都会给出警告,这在我看来更为正确。我关闭了您示例的优化,删除了volatile关键字,但仍然没有收到任何警告:@xaxxon
-Warray bounds
需要
-ftree vrp
,默认情况下,它是使用
-O2
@xaxxon打开的。请查找文档以查找
-ftree vrp
可能需要一些其他标志:这不像启用它那么简单连同
-O0