It hurts to see how popular compilers like GCC happily allows for undefined behavior as the default action instead of breaking when the index operator is used,
You might as well say it hurts to see things programmed the way the standard requires.
Well, there isn't any.
But I think the difference is that some code requires you to write the check. Take for instance if you were going to use an index from the untrustworthy end-user:
Code:
size_t userindex = tools::getint("prompt >");
if (0 < userindex && userindex << somearray.size())
foo(somearray[userindex]);
It's quite plain how at can help.
In code like this:
Code:
for (size_t i = 0; i < somearray.size(); i++)
foo(somearray.at(i));
As written, the only way this messes up is if the type of somearray actually has a broken interface. As I said, it has a perception of being unnecessary. It is even becoming more unnecessary with certain new features of C++, like the range based for loop.