jpo38 jpo38 - 22 days ago 9
C++ Question

Why MSVC compiler does not detect std::array out of bound access

I replaced an old style array by a

std::array
, but then I realized compiler (at least MSVC) was doing less bound checking. Consider this code:

double myArray[10];
myArray[11] = 3.0;

std::array<double,10> myStdArray;
myStdArray[11] = 3.0;


Fo myArray, a warning is reported:


warning C4789: buffer 'myArray' of size 80 bytes will be overrun; 8 bytes will be written starting at offset 88


For
myStdArray
, no warning is reported at all.

Is it a "bug" in the compiler or does the way
std::array
is implemented does not allow this kind of warning to be reported? If so, is it worth using
std::array
that appears to be less safe here...

Answer

You can use std::get to get a guaranteed error if your access is out of bounds. The index must be known at the compile time, of course.

std::array<double,10> myStdArray;
std::get<9>(myStdArray) = 3.0; // ok
std::get<11>(myStdArray) = 3.0; // error

As to the other part of your question: this might be conjecture on my part, but the standard library should be considered "magical" in the way that the compiler knows its contracts and there's nothing making it impossible for it to perform fact checking.

This is easily provable with the following example. Both clang and gcc elide the memset call in favour of direct write in the following function:

void zero_int(int* ptr)
{
  memset(ptr, 0, sizeof(int));
}

compiler explorer

So, to the best of my knowledge there's nothing preventing the compiler from emitting warnings in your code, except for potential implementation difficulty/cost.

Comments