Is it possible to enable array bounds checking in g++?
Asked Answered
S

5

19

Is it possible to have g++ show an error when compiling the following file with some flag?

#include <iostream>
using namespace std;

int main()
{
   int arr[ 2 ];

   cout << arr[ 4 ] << endl;

   return 0;
}

I saw some things like gcc -Wall -O2 main.c which only works with C, not C++.

Siphonophore answered 24/1, 2011 at 4:9 Comment(1)
-Wall -Wextra -ansi -pedantic don't generate warnings for this program :(Grosso
C
7

You can use a static analyser such as Cppcheck. When run on your above code:

$ cppcheck --enable=all test.cpp
Checking test.cpp...
[test.cpp:6]: (style) Variable 'arr' is not assigned a value
[test.cpp:8]: (error) Array 'arr[2]' index 4 out of bounds

You can integrate Cppcheck into your build procedure and consider your code built successfully only if Cppcheck passes.

Callihan answered 24/1, 2011 at 20:56 Comment(0)
G
8

Not at compile time. You might be able to check that at runtime though.

For that take a look at: Runtime array bounds checking with g++

Guinea answered 24/1, 2011 at 4:16 Comment(0)
C
7

You can use a static analyser such as Cppcheck. When run on your above code:

$ cppcheck --enable=all test.cpp
Checking test.cpp...
[test.cpp:6]: (style) Variable 'arr' is not assigned a value
[test.cpp:8]: (error) Array 'arr[2]' index 4 out of bounds

You can integrate Cppcheck into your build procedure and consider your code built successfully only if Cppcheck passes.

Callihan answered 24/1, 2011 at 20:56 Comment(0)
C
3

For raw arrays, I don't think so, because -fbounds-check didn't work with your example and MingW g++ 4.4.1, and because the old 3.x docs I have say

-fbounds-check

For front-ends that support it, generate additional code to check that indices used to access arrays are within the declared range. This is currently only supported by the Java and Fortran 77 front-ends, where this option defaults to true and false respectively.

However, with std::vector you can use at to have a slightly impractical run-time bounds-checking (generates exception). And you can use a special debug version of the standard library, that provides practical run-time bounds-checking for []. For example, when compiling…

#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int>  arr( 2 );

   cout << arr[ 4 ] << endl;
}

… you get different respectively non-checking and checking behavior for the release and debug versions of the g++ standard library implementation:

C:\test> g++ x.cpp & a
4083049

C:\test> g++ x.cpp -D _GLIBCXX_DEBUG -D _GLIBCXX_DEBUG_PEDANTIC & a
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/debug/vector:265:
    error: attempt to subscript container with out-of-bounds index 4, but
    container only holds 2 elements.

Objects involved in the operation:
sequence "this" @ 0x0x22ff1c {
  type = NSt7__debug6vectorIiSaIiEEE;
}

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

C:\test> _

Reportedly for newer g++ versions (after 4.0) you don't need the _GLIBCXX_DEBUG_PEDANTIC symbol. For details, see the GNU documentation.

Cheers & hth.,

Cowgill answered 24/1, 2011 at 5:6 Comment(2)
{boost,std::tr1,std}::array has at as well.Discobolus
The -fbounds-check seems to only work if optimizations are turned on. So I expected -O -fbounds-check to work - but it doesn't in the OP's example just like you said. However -fsanitize=address,undefined does catch it: godbolt.org/z/5MPx3d668Aspergillum
G
2

I recall seeing a gcc or g++ warning message from ffmpeg or x264 along the lines of

"warning index of array may be out of bounds"

http://gcc.gnu.org/ml/gcc/2000-07/msg01000.html

seems like it probably made it in.

The constraint is that you have an example like yours above. as soon as you have have variables instead of literals it is not possible. except perhaps in a simple loop.

Grosso answered 24/1, 2011 at 4:27 Comment(1)
According to Wikipedia, ffmpeg uses AddressSanitizer. This might be its output. More on AddressSanitizer in an A to another Q.Dunham
Z
0

You can replace arrays with std::vector. Vector has accessor member function (std::vector::at) that does bounds checking at runtime.

Compile time check for buffer overflow is a very hard undecidable problem, unfortunately. It's usually handled by a full blown static analysis tool.

Zionism answered 24/1, 2011 at 4:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.