Why isn't gcc complaining about array bounds even if requested?

Viewed 2141

I'm using gcc 4.9.0 and I would like to see compiler warn me about exceeded array bounds. If I compile this

int main()
{
    int table[5]={0};
    table[8] = 1234;
    int x = table[10];
}

with g++ -O2 -Wall main.cpp -o main.exe I only get warning about unused x:

main.cpp: In function 'int main()':
main.cpp:8:7: warning: unused variable 'x' [-Wunused-variable]
int x = table[10];
   ^

From gcc documentation (https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options) I see that -O2 together with -Wall should enable -Warray-bounds=1 check. Things don't change if I try to add -Warray-bounds. As a matter of fact, the compiler doesn't even recognize -Warray-bounds=1:

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

Now, why doesn't compiler give any warning about incorrectly writing into / reading from the array? And why doesn't the compiler recognize '-Warray-bounds=1'?

2 Answers

Probably compiler optimizes it away. Try making table volatile.

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

produces:

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];
             ~~~~~~~~^

Here's a live example.


From -Warray-bounds docs:

It warns about subscripts to arrays that are always out of bounds

My guess is that g++ decides not to warn when the access never actually happens.


As a matter of fact, the compiler doesn't even recognize -Warray-bounds=1:

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

g++-4.9.0 does not support command in the format -Warray-bounds=n, but it will work just fine with -Warray-bounds. -Warray-bounds=n is supported from g++-5.1.0.

I suspect that the lack of warnings is because of optimization. It is easy for the compiler to see that none of the lines you wrote have any effect on the behaviour of the program, and may have therefore chosen to simply skip those lines.

It would appear that the phase that checks compile time known out of bound accesses happened to have been performed after the removal of unused code, so GCC never saw your bug.

A trivial way to prevent such optimization is to declare the array volatile. Any write or read of volatile object must be considered as a side effect by the compiler and therefore cannot be optimized away.

Related