Why doesn't the compiler stop me from indexing into an array using integers greater than the length of the array minus one and negative integers?
What is the rationale behind allowing this?
Why doesn't the compiler stop me from indexing into an array using integers greater than the length of the array minus one and negative integers?
What is the rationale behind allowing this?
Well the compiler can't because that's a runtime provision.
But why does the std::vector
not bounds check the []
operator. This is because there is already a bounds checked method at()
. This performs bounds checking and throws an exception if the index is out of bounds.
But the C++ principle of not paying for what you don't use is also at play. Why should you check for an out of bounds exception if you have already guaranteed it is in bounds.
for(int loop = 0; loop < cont.size(); ++loop) {
std::cout << cont[loop] << "\n"; // Do I need to bounds check here?
} // loop is guaranteed to be in range
// why should I pay for the cost of
// of a check? So beginners don;t make
// mistakes?
So if you want bounds checked access use at()
if you want unchecked use []
.
From the comments:
Why does p[-10]
work? Because on pointer types this is simply syntactic sugar for *(p - 10)
. That a lot harder to check for validity then you think.
int q[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int* p = q + 11;
std::cout << p[-10]; // This is valid operation.
The C++ runtime does not keep track of the size of arrays, so there is no way to prevent indexing past the end of the array.
Indexing negative values can be useful if you have a pointer to a location in the middle of an array. For example:
int a[] = { 1, 2, 3, 4, 5 };
int *p = &a[2];
std::cout << p[-1] << std::endl;
This will print 2, since p
points to the element containing 3.