5

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'?

3
  • clang still warns about it regardless of optimization. godbolt.org/g/e6yv89 gcc doesn't warn about it, regardless of optimizations: wandbox.org/permlink/gLXfIl7dd87Uwsew Commented Sep 26, 2017 at 8:37
  • Note that the doc you link to is for the latest version of gcc, so it might differ from the one for 4.9. Commented Sep 26, 2017 at 9:55
  • You don't use =1 or =0 with -W options. Only -Wsome-warning or -Wno-some-warning. Commented Sep 26, 2017 at 11:24

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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.

4 Comments

The code is still compiled, so it's odd that optimizations would make the warning not show up. Clang gives the warning regardless of optimization level, which seems more correct to me. godbolt.org/g/e6yv89
I turned off optimization on your example and removed the volatile keyword and still got no warning: wandbox.org/permlink/gLXfIl7dd87Uwsew
@xaxxon -Warray-bounds requires -ftree-vrp which is on by default with -O2
@xaxxon please look up docs for -ftree-vrp probably it requires some other flags: it is not as easy as just enabling it together with -O0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.