Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(learning) out_of_range exception is not working(?)

31 views
Skip to first unread message

Christiano

unread,
Jan 24, 2017, 4:56:04 PM1/24/17
to
Please, see the code at the end of this post.

Compiling and running:
debian@debian:~/principles$ g++ -std=c++11 throw.cpp
debian@debian:~/principles$ ./a.out
1 2 3 4 5
v[0]==1
v[1]==2
v[2]==3
v[3]==4
v[4]==5
v[5]==0
debian@debian:~/principles$

The expected output
debian@debian:~/principles$ g++ -std=c++11 throw.cpp
debian@debian:~/principles$ ./a.out
1 2 3 4 5
v[0]==1
v[1]==2
v[2]==3
v[3]==4
v[4]==5
Ops, range error
debian@debian:~/principles$

Please, what have I done wrong?

////////// Code: /////////////
#include <iostream>
#include <vector>
#include <stdexcept>
using namespace std;

int main(void)
try
{
vector<int> v;
for(int x;cin>>x;)
v.push_back(x);

for(int i=0;i<=v.size();++i)
cout << "v[" << i << "]=="<<v[i]<<'\n';

}
catch(out_of_range)
{
cerr << "Ops, range error\n";

return 1;
}
catch(...)
{
cerr <<"Exception: something get wrong\n";

return 2;
}

Öö Tiib

unread,
Jan 24, 2017, 5:25:42 PM1/24/17
to
On Tuesday, 24 January 2017 23:56:04 UTC+2, Christiano wrote:
> Please, see the code at the end of this post.

You mix things up perhaps. The 'std::vector::at' member is required to
throw 'std::out_of_range' if index violates vector bounds.

The behavior of program that contains 'std::vector::operator[]'
call with out of bounds index is undefined.

Undefined behavior may be whatever. It may output "v[5]==0"
or it may crash or it may conjure demons out of your nose.
Generally we avoid writing code that contains undefined behaviors.

Christiano

unread,
Jan 24, 2017, 6:39:57 PM1/24/17
to
Hi, thank you. I have rewritten the code (at the end of this post) adding ".at" instead .[x]. Now it is working as expected:
debian@debian:~/principles$ ./a.out
1 2 3 4 5
v[0]==1
v[1]==2
v[2]==3
v[3]==4
v[4]==5
Ops, range error
debian@debian:~/principles$

So this must be an error in PPP2 (principles and practices programming using c ++ second edition).
See the page 149:
http://imgur.com/a/E9m6Q

/// my new code2
#include <iostream>
#include <vector>
#include <stdexcept>
using namespace std;

int main(void)
try
{
vector<int> v;
for(int x;cin>>x;)
v.push_back(x);

for(int i=0;i<=v.size();++i)
cout << "v[" << i << "]=="<<v.at(i)<<'\n';

Alf P. Steinbach

unread,
Jan 24, 2017, 6:56:02 PM1/24/17
to
It's just a unclear language, in the sense of using /too few words/ to
explain something, so that the point flies by the casual reader like a
passenger jet high above: such a jet liner is usually not even noticed.

“[The subscript operation] can check (and the `vector` we are using does”

You need to read that five times, say, in order to get the word count up
to an appropriate level commensurate with its importance. ;-)

That said, the wording is misleading in that it indicates that a given
vector implementation will either have a bounds-checking `operator[]` or
not. More commonly this can be specified when you build your program,
and instead of throwing an exception, it might just terminate the
program. The options for turning on and off such checking vary greatly
between compilers; it's not specified by the Holy Standard.

At one time great debates raged here in clc++ about whether using `.at`
was a good idea in order to catch subscript range errors. I can't
remember any consensus being reached. But it's worth noting that with
most compilers, with proper tool usage you can do this also with simple
`[i]` indexing, possibly with crash response instead of exception.

Cheers & hth.,

- Alf

Christiano

unread,
Jan 24, 2017, 7:38:09 PM1/24/17
to
Hi, Alf, Thank you, you made me remember that the author occultly uses a header:
http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

So I decided to investigate if he was doing a special vector version, as you said.

See this code section:
template< class T> struct Vector : public std::vector<T> {
using size_type = typename std::vector<T>::size_type;

#ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n,v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
#else
using std::vector<T>::vector; // inheriting constructor
#endif

T& operator[](unsigned int i) // rather than return at(i);
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
const T& operator[](unsigned int i) const
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
};

More specifically this part:

T& operator[](unsigned int i) // rather than return at(i);
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}

I'm still learning c ++, but I can see by this code that he creates its own vector version, through inheritance, specializing the operator[].

Conclusions:
1-The standard vector in STL doesn't throw out_of_range when out of range indexing.
2-Using standard vector STL, If you want this characteristic you have to use .at(index)
3-The examples in book PPP2 use a modified vector which throws out of range indexing.

Alf P. Steinbach

unread,
Jan 24, 2017, 8:05:38 PM1/24/17
to
On 25.01.2017 00:56, Stefan Ram wrote:
> Christiano <chris...@engineer.com> writes:
>> So this must be an error in PPP2 (principles and practices
>> programming using c ++ second edition).
>> See the page 149:
>
> I don't watch pictures from web sites, but I don't
> believe that you represented the title of the book
> correctly, and I don't believe that a book co-authored
> by Bjarne Stroustrup contains such a blatand mistake.

Oh, it does have (blatant) mistakes, as do all books.

And in this particular book there's a really nasty use of a macro, that
turned out to unexpectedly bite some novices using the book. I don't
recall exactly what now. But that macro thing is very ungood: I didn't
and still don't understand how such a thing could end up in that book.

Anyway, the nice thing about Bjarne's books is that they have online
errata pages, at least the various “The C++ Programming Language”
editions do. That makes them trustworthy in a way. You know that if
there is an egregious error, and all books have them!, then Bjarne is
absolutely not afraid of publishing that error and have it corrected.


Cheers!,

- Alf

Gareth Owen

unread,
Jan 25, 2017, 3:28:46 AM1/25/17
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> (And I only now have become aware of that the way that he
> uses the braces in the method declarations of this program
> seems to be the way I use them:
> »{« at the start of a line, followed by a space,
> »}« at the end of a line, preceded by a space.)

I think a lot of people brace functions like that, if and only if the
body of the function is a single statement, or fits on a single line.

Using it anywhere else remains a crime against readability.
0 new messages