Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bound checking of std::array in "Debug" version of GCC

Tags:

c++

arrays

c++11

Benefits of C++11 std::arrays when programming have been explained by experts, but there is one thing I would like to get from the compiler. Ability to turn ON range check that is default when using .at() while compiling the code that uses [].

It could be beneficial for checking range violations especially for multidimensional arrays because in that case it is less likely that range violation will cause segfault(because you often own memory around the inner array so [5000][-123] will still likely point to memory that you own).

So I would like to know if there is a switch that will compile into machine code that checks ranges:

    const uint32_t dim1=10*1000,dim2=3;
    std::array<std::array<int, dim2>, dim1> test_2Darray;
    int undefined_value=test_2Darray[dim2-1][dim1-1];
    std::cout<<"ouch ("<<undefined_value<<")"<<std::endl;
    int ok_value=test_2Darray[dim1-1][dim2-1];
    std::cout<<"OK   ("<<ok_value<<")"<<std::endl;
    //  test_2Darray.at(dim2-1).at(dim1-1); -->terminate called after throwing an instance of 'std::out_of_range'
    //      what():  array::at

If you ask why I don't switch to .at() - I might need the performance, also I have a lot of code with [] already written and I'm not smart enough to smart to do replace for 1D let alone 2D arrays.

I use GCC 4.6

like image 318
NoSenseEtAl Avatar asked Feb 03 '23 11:02

NoSenseEtAl


1 Answers

It looks like the array that comes with gcc 4.6 doesn't have a debug mode yet. Understandable since C++11 support is still experimental.

There is a flag _GLIBCXX_DEBUG which is usually used to turn on debug mode. If you look at /usr/include/c++/4.6/debug/vector:313 you'll see operator[] has:

__glibcxx_check_subscript(__n);

Now, this may be uber-evil (and I mean really evil) but it looks like we can conditionally add this to array. Change lines 148-154 of /usr/include/c++/4.6/array from:

reference
operator[](size_type __n)
{ return _M_instance[__n]; }

const_reference
operator[](size_type __n) const
{ return _M_instance[__n]; }

to:

reference
operator[](size_type __n)
{
#ifdef _GLIBCXX_DEBUG
    __glibcxx_check_subscript(__n);
#endif
    return _M_instance[__n];
}

const_reference
operator[](size_type __n) const
{
#ifdef _GLIBCXX_DEBUG
    __glibcxx_check_subscript(__n);
#endif
    return _M_instance[__n];
}

This means you can enable bounds checking for array the same way you do for vector and other stl debugging - by adding -D_GLIBCXX_DEBUG to your compile line. E.g.:

g++ someAwesomeProgram.cpp -D_GLIBCXX_DEBUG

I just had a look at gcc trunk and apparently there is no reference to _GLIBCXX_DEBUG for array yet :(. http://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/include/std/array

Hopefully it's not too far away. I imagine we will have safe iterators and all that for array in debug mode soon enough. In the meantime, this can be our little secret :-).

like image 171
voltrevo Avatar answered Feb 05 '23 15:02

voltrevo