Reputation: 548
I have a couple of questions concerning C++ exceptions. For reference, I am learning C++ through Bjarne Stroustrup's "Programming Principles and Practice using C++".
My first questions I think is simple: around page 147, we are talking about exceptions dealing with referencing an index outside of the range of a vector. So his try catch block is
int main(){
try{
vector<int> v;
int x;
while(cin>>x)
v.push_back(x);
for(int i = 0; i<=v.size();i++)
cout<<"v["<<i<<"] == "<<v[i]<<endl;
} catch (out_of_range_error){
cerr<<"Oops! Range error\n"
return 1;
} catch(...){
cerr<<"Exception: something went wrong\n";
return 2;
}
}
So my question is what is out_of_range_error ?! Early on in the book he mentions the use of a header file to use so new people need not concern themselves with nuances. That file is located here but out_of_range_error is no where there. Just the standard out_of_range exception you can check for normally (after importing stdexcept). And even when I use that file (which I normally don't) the compiler (g++) tells me it expects an identifier for out_of_range_error. So is this just some typo in this mass-produced book? Or am I missing something?
My second question is on the same topic, if I don't import the file he gives, but instead just do:
#include <iostream>
#include <stdexcept>
#include <vector>
using namespace std;
/*
#include "std_lib_facilities.h"
*/
int main()
{
try
{
vector<int> newVec;
int x;
while(cin>>x)
newVec.push_back(x);
for(int i = 0; i<=newVec.size()+200;i++)
cout<<newVec[i]<<endl;
return 0;
}//try
catch (out_of_range)
{
cerr<<"runtime error: "<<endl;
return 1;
}//catch
}//main()
then my code runs with no call to the catch block, even though I reference newVec[newVec.size()+200] in the end. It just returns a bunch of 0s with other integers randomly strewn about. I expect these are just the next bits of memory that would have been allocated for newVec, Vector is not special here, the same thing happens with arrays.
So why does C++ not do any range checking? Or does it do range checking and just not care?
If I use
vector<int> v(10);
v.at(20) = 100;
then I get an error, but if I just want to reference, or assign to, v[20] I get no problems. Why is this?
Is this common in C++? Do you often need extra code to FORCE C++ to notice array bounds? This seems very hazardous, coming from a java background. Java would immediately alert you to any indexing errors, but C++ seems content to let you carry on with incorrect logic.
Thanks so much for any responses, sorry for a long-winded attempt at asking this question.
Upvotes: 1
Views: 311
Reputation: 310980
Relative to your first question then I am sure that out_of_range_error
is a typo. There should be out_of_range
(See section 19.4 of the book for additional information).
As for the second question then operator []
for vectors does not throw the exception std::out_of_range
it simulates the bahaviour of arrays. So there is simply undefined behaviour. If you want that there would be a check of the range then you have to use member function at
By the way if the book has errate at the site then you should look through it.
Upvotes: 2
Reputation: 137315
One of the most important principles motivating the design of C++ and its standard library is "you don't pay for what you don't need".
Properly written code shouldn't be accessing array (or vector) out of bounds, therefore they don't need bounds checking, and therefore they shouldn't be forced to pay for it. Bounds checking can easily double the cost of an array access. Similar designs can be seen throughout the C++ standard library - for example, std::lock_guard
vs. std::unique_lock
, std::condition_variable
vs. std::condition_variable_any
. In each case the latter class adds extra functionality at extra cost, so users who don't need the extra functionality could simply use the more lightweight version.
If you do need bounds checking, then std::vector
provides the member function at()
for this purpose.
Upvotes: 1