简体   繁体   中英

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...

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.

myArray[11] is language built-in functionality which the compiler knows about and which the compiler can warn for.

myStdArray[11] is short for myStdArray.operator[](11) , which is a function call where 11 is well in the parameter type's range. Warning for this requires looking into operator[] 's function body, which is something that typically only happens if the function gets inlined.

Furthermore, vendor extensions may make myStdArray.operator[](11) well-defined, eg as aborting the program in debug mode, and in such implementations it's very difficult to get a useful compile-time warning.

However, with such extensions, the added run-time safety may still outweigh the lack of compile-time warnings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM