I have seen many times that std::string::operator[]
does not do any bounds checking. Even What is the difference between string::at and string::operator[]?, asked in 2013, the answers say that operator[]
does not do any bounds checking.
My issue with this is if I look at the standard (in this case draft N3797) in [string.access] we have
const_reference operator[](size_type pos) const; reference operator[](size_type pos);
- Requires:
pos <= size()
.- Returns:
*(begin() + pos)
ifpos < size()
. Otherwise, returns a reference to an object of typecharT
with valuecharT()
, where modifying the object leads to undefined behavior.- Throws: Nothing.
- Complexity: constant time.
This leads me to believe that operator[]
has to do some sort of bounds checking to determine if it needs to return a element of the string or a default charT
. Is this assumption correct and operator[]
is now required to do bounds checking?
std::array provides many benefits over built-in arrays, such as preventing automatic decay into a pointer, maintaining the array size, providing bounds checking, and allowing the use of C++ container operations.
One of the most useful data types supplied in the C++ libraries is the string. A string is a variable that stores a sequence of letters or other characters, such as "Hello" or "May 10th is my birthday!". Just like the other data types, to create a string we first declare it, then we can store a value in it.
This is due to the fact that C++ does not do bounds checking. Languages like Java and python have bounds checking so if you try to access an out of bounds element, they throw an error. C++ design principle was that it shouldn't be slower than the equivalent C code, and C doesn't do array bounds checking.
Many programming languages, such as C, never perform automatic bounds checking to raise speed. However, this leaves many off-by-one errors and buffer overflows uncaught. Many programmers believe these languages sacrifice too much for rapid execution.
The wording is slightly confusing, but if you study it in detail you'll find that it's actually very precise.
It says this:
[]
is either = n or it's < n.charT()
(i.e. the null character).But no rule is defined for when you break the precondition, and the check for = n can be satisfied implicitly (but isn't explicitly mandated to be) by actually storing a charT()
at position n.
So implementations don't need to perform any bounds checking… and the common ones won't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With