Mac M1.
I learn C++ by Bjarne Stroustrup’s book. He show the similar example in his "Programming. Principles and Practice Using C++" book (chapter 5.6.2). Also he writes this exception (out_of_range) is to be occurred.
clang++ --version
Apple clang version 16.0.0 (clang-1600.0.26.4)
Target: arm64-apple-darwin24.0.0
Thread model: posix
My code:
#include <iostream>
#include <vector>
int main(){
try{
std::vector<int> items;
constexpr int size = 5;
for(int i = 0; i < size; ++i){
items.push_back(i * 10);
}
for(int i = 0; i <= items.size(); ++i){ // out of range!
std::cout << i << " -> " << items[i] << std::endl;
}
std::cout << "Success!" << std::endl;
}
catch (std::out_of_range){
std::cerr << "Range error!" << std::endl;
}
catch(...){
std::cerr << "Something wrong..." << std::endl;
}
}
Compilation command:
clang++ -std=c++20 main.cpp
Result:
./a.out
0 -> 0
1 -> 10
2 -> 20
3 -> 30
4 -> 40
5 -> 0
Success!
I’ve expected to get the out of range exception but it wasn’t happened. Why?
>Solution :
std::vector‘s operator[] doesn’t perform any validity check on the index. If it is out-of-bounds, then that’s a violation of operator[]‘s preconditions and therefore undefined behavior. Undefined behavior means that anything can happen. Throwing an exception is permissible (in in debug builds the compiler might to that), but producing non-sense or crashing are just as valid.
std::vector also has the .at member function which doesn’t have the precondition that the index is in-bounds and instead throws a std::out_of_bounds exception if the index is not in-bounds. It seems that you wanted to use that:
for(int i = 0; i <= items.size(); ++i){ // out of range
std::cout << i << " -> " << items.at(i) << std::endl;
}
However, in general .at is not used often. Accessing the vector out-of-bounds is usually an indicator for a program logic flaw that shouldn’t happen at all and not just an exceptional execution flow that is intended to happen. Exceptions are not usually a solution to a programming error.