1

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.

13
  • 2
    You should limit yourself to one post at a time. C++ doesn't do bounds checking because you shouldn't pay for what you don't need. But std::vector has element access method at(), which does range checking. So if you want range checking, you can pay for it by using at(). Commented Sep 9, 2014 at 20:32
  • Interesting. This seems dangerous, but I suppose its just a quirk to make sure your own algorithms always have the correct bounds. I'll have to go check all my previous code! I have guessed (should I use < or <= here?) a few times with the thought the compiler would yell at me sooner or later. Commented Sep 9, 2014 at 20:36
  • 1
    I think this has changed in later revisions to out_of_range. Which revision do you use? Furthermore, I think we should read Vector<int>, i.e. he's using his own vector, not the StdLib one. Commented Sep 9, 2014 at 20:39
  • I concur with the above comment. C++ is all about efficiency; the index notation translates to simply an index from the start of the allocated buffer (a couple of machine instructions). According to cplusplus.com/reference/stdexcept/out_of_range, the ::at(idx) accessor of some containers can do the checking. Your code should avoid working with fixed index values and use algorithms instead to find, sort, parse etc. Commented Sep 9, 2014 at 20:42
  • 3
    You must be using a really early printing. This errata has pg 147: s/out_of_range_error/out_of_range/. Commented Sep 9, 2014 at 20:59

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.