Questions about Error handling

Hello Folks,
I'm currently working through the beginner c++ book by Stroustrop and i'm up to the errors chapter.
Stroustrop gives the following example program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "../../std_lib_facilities.h"

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;
    return 0;
} 

catch (out_of_range_error) {
    cerr << "Oops! Range error\n";
    return 1;
} 

catch (...) {
    cerr << "Exception: Something went wrong\n";
    return 2;
}


now a few things are very unclear for me here:

1) does the catch command actually do anything, if no "throw" command is specified? I guess the "throw" command is part of the vector class?

2) The program does not compile.

The error messages i get are:
Line 13: syntax error - identifier 'out of range error'
Line 13: catch handlers must specify one type

Am i missing an include?

Either you can cascade the exception to upper levels by rethrowing them. Or you can just break the chain by not throwing and just returning error codes.

I dont know whats inside std_lib_facilities.h. you need to include iostream and vector.

It should be

catch (out_of_range error)
closed account (zb0S216C)
Fauch911 wrote:
"1) does the catch command actually do anything, if no "throw" command is specified?"

If nothing is thrown, then "catch" blocks are never executed simply because there would be no reason to. Also, "throw" is not specific to any class. "throw" is an operator that throws exceptions and is accessible globally.

Fauch911 wrote:
"2) The program does not compile.

The error messages i get are:
Line 13: syntax error - identifier 'out of range error'
Line 13: catch handlers must specify one type

Am i missing an include?
"

That "#include" looks strange to me. When "std::vector" attempts to access an element that's beyond its reach, it'll throw a "std::out_of_range" exception; I don't know what "out_of_range_error" is.

See here for more information on exceptions: http://www.cplusplus.com/doc/tutorial/exceptions/

Wazzak
Hello!

First of all: Thank you.

1)
 
catch (out_of_range error)

gets my program to compile, obviously a typo in my script.

2)
Instead of throwing an exception, which is supposed to happen when my program acesses the member of the vector v[v.size()] my program just returns a 'random' value, so no exception is raised.

3)
I dont understand what you mean by "cascading the exception to upper levels". From what I understood so far: c++ handles errors on two levels: by throwing an exception (function returns exception) and by catching an exception (code which tells the program how to handle an exception if it is raised)

In the program written here there is no "throw" command. So, how can an exception be caught in the first place?


edit: both <vector> and <iostream> are included.

@wazzak:

the include merely includes a few popular includes like <vector> <iostream>. when i include those, exactly the same happens.


If nothing is thrown, then "catch" blocks are never executed simply because there would be no reason to. Also, "throw" is not specific to any class. "throw" is an operator that throws exceptions and is accessible globally.


Thanks for the clarification. However my program does not raise an exception when i access an element beyond the vectors reach - it simply gives me a "random" number ".


Last edited on
closed account (zb0S216C)
Fauch911 wrote:
"vector v[v.size()] my program just returns a 'random' value, so no exception is raised."

The "std::vector" has two means of accessing its elements: "std::vector::at( )" and "std::vector::operator []".

"std::vector::at( )" will throw an exception if the index you give it is beyond the upper-bound index.
"std::vector::operator []" will not throw an exception if the index you give it is beyond the upper-bound index.

Fauch911 wrote:
"I dont understand what you mean by "cascading the exception to upper levels"."

S/he means that when an exception is thrown inside a function, the exception will be thrown from one function to the next until the exception is caught. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Function_A( )
{
  throw( an_exception );
}

void Function_B( )
{
  Function_A( );
}

void Function_C( )
{
  Function_B( );
}

int main( )
{
  try
  {
    Function_C( );
  }

  catch( the_exception )
  {
  }
}

Here, "Function_C( )" calls "Function_B( )" which calls "Function_A( )". "Function_A( )" then throws an exception, but because "Function_A( )" contains no "catch" blocks, it cannot handle the exception. So, the exception is thrown to "Function_B( )". Because "Function_B( )" contains no "catch" blocks, it cannot handle the exception so "Function_B( )" re-throws the exception to "Function_C( )". "Function_C( )", too, contains no "catch" blocks, so it too re-throws the exception to "main( )". Because "main( )" contains a "catch" handler, the exception is handled and will not be thrown again unless explicitly told to do so.

Fauch911 wrote:
"In the program written here there is no "throw" command. So, how can an exception be caught in the first place?"

Just because there's no visible "throw" statement, one cannot assume that exceptions are never thrown by classes, functions and operators.

Wazzak
Last edited on
fair enough - so is the program i provided above [original from Stroustrups script] even capable of throwing an expression it could catch via

1
2
3
4
catch (out_of_range_error) {
    cerr << "Oops! Range error\n";
    return 1;
} 


since it only accesses the vectors elements via std::vector::operator [] ?

edit: thanks for the part about cascading - i understood that now.
Last edited on
yes, its capable of throwing.
Exceptions are derived from std::exception class and they have a what() method to know what exactly happened. So, using error.what() will be a good idea.

Thanks @Framework for clarifying my part. :-)
Last edited on
closed account (zb0S216C)
No, as I said previously, accessing a "std::vector" through the sub-script operator ("[]") will never throw an exception, but "std::vector::at( )" will.

Wazzak
Last edited on
the last time it goes through that for loop it'll throw and you should see your "Oops! range error" message.
that answer is not entirely satisfactory. you tell me it's capable of throwing even though

"std::vector::operator []" will not throw an exception if the index you give it is beyond the upper-bound index.


How can i catch the exception if the member function does not throw it?

You gotta understand that these are beginners/basic questions about exceptions.

mutexe (107)
the last time it goes through that for loop it'll throw and you should see your "Oops! range error" message.


i realize thats the intention behind the program. The problem is that is not whats happening.
Last edited on
I just said that the vector class is capable of throwing exceptions and other std library classes. I assumed that you have read what was written already in previous posts.

So obviously, if you use [] and try to catch exceptions, my statement is wrong. you are a beginner and which we understand but you will have to apply some aptitude.

try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
	vector<int> v;
	v.resize(10);
	try {
		
		v.at(11);
		return 0;
		} 

	catch (out_of_range error) {
		cerr << error.what();
		return 1;
	} 
}
Last edited on
i'm using visual studio..

if i use
v.at(i)
in the for loop, then your "Oops! Range error" does indeed get printed.

if i use
v[i]

then i get an assert from inside the actual vector class itself. something like "vector subscript out of range".


p.s. and in my opinion i don't think Stroustrop's book is great for beginners.
Last edited on
closed account (zb0S216C)
Fauch911 wrote:
"How can i catch the exception if the member function does not throw it?"

I didn't implement the "std::vector" so I can't tell you why it doesn't throw an exception. If nothing is thrown, nothing can be caught; as simple as that.

mutexe wrote:
"then i get an assert from inside the actual vector class itself."

That's because you're accessing an element that doesn't exist (the constructor of that element had not yet been called so it technically doesn't exist).

Wazzak
Last edited on
summing things up - The problem is solved :)
Using

 
v.at(i)


the program does exactly what it is supposed to do.

@writetonsharma

I understand what you are trying to tell me, but imagine you are a beginner and you are reading a script from the creator of c++ which provides a program which does not do what it is supposed to do :) - you'd be confused too most likely.

Thanks to everyone, especially Framework for providing exactly the answers i was looking for.
Last edited on
That's because you're accessing an element that doesn't exists (the constructor of that element had not yet been called so it technically doesn't exist).


yes, i know why, i was just explaining the differences to him.
Topic archived. No new replies allowed.