About std::exception --- Don't understand interface

Hi:

My questions are about std::exception.
I'm trying to define my own custom exception classes, say:
1
2
3
4
5
6
7
class IndexOutOfBoundary : public exception
{
};

class InvalidValue : public exception
{
};


My understanding is: depending on the types of exception caught, my program is going to take different actions, say:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try
{
   function1();//function1() has a throw statement; might throw either of the two custom exceptions: IndexOutOfBoundary or InvalidValue
}
catch(IndexOutOfBoundary & e)
{
   cout << "Index is out of boundary\n"; // toy example
}
catch(InvalidValue & e)
{
   cout << "Value is invalid\n"; // toy example
}
catch()
{
   cout << "Something else is caught\n";
};


Apparently, I'm trying to navigate my program's exception handling process by the custom exception type. Therefore, I don't need to override member functions of std::exception, whose declarations can be found in the link --- http://www.cplusplus.com/reference/std/exception/exception/

Question 1:
Is it a good style to use exception? If not, please provide an advisable way of using it.

Question 2:
I don't understand the declaration of the member functions in std::exception.
For instance:
1
2
3
4
5
6
7
8
class exception {
public:
  exception () throw(); // Is it legal? What does it mean by "exception ()"? If throw() is the function name, then "exception ()" should be replaced by an object type thrown. In this case, I think it's "exception".
  exception (const exception&) throw(); // similar to the previous question. In addition, what's the extra "const exception &"?
  exception& operator= (const exception&) throw();
  virtual ~exception() throw();
  virtual const char* what() const throw(); // what is "what()"
}



I've detailed my questions in the comment. In short, I just have no idea what it is talking about. The link claims exception () throw () is the default constructor. But I've never seen any constructor in this form. What's the postfix throw ()? And where is the declaration for "throw()"?




Please enlighten me. Many thanks in advance!
closed account (3hM2Nwbp)
1) You're likely to get many varying responses.

Generally, I believe that code should speak for itself as you read it. So if making an IndexOutOfBoundsException would make the error condition more explicit in the handling code, I would do it. Some people will say to only make a new exception if you have something to add to the class.

2) Much C++ documentation leaves much to be desired. The throw() is a throw specifier that is generally discouraged in production code. Microsoft's compiler is the only one that I know about that will make performance optimizations based on a no-throw specified method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class exception {
public:
  
  // Constructs an exception with no message
  exception () throw();

  // Copy-constructs an exception
  exception (const exception&) throw();

  // Sets this exception equal to the provided one
  exception& operator= (const exception&) throw();
  
  // Destroys an exception
  virtual ~exception() throw();

  // Retrieves a message containing information about the exceptional circumstance
  // This method is overridden by sub-types of exception.
  virtual const char* what() const throw();
}
Last edited on
As you see class exception has a virtual method what() which will give you info about what kind of exeption has been thrown.

you need to override that function which will print out that exception of your class has been thrown!

since you've inherited that class you must use a base class in your exeption handler like this:

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
27
#include <iostream>
#include <exception>
using namespace std;

class IndexOutOfBoundary : public exception
{
      // OVERIDE BASE CLASS VIRTUAL METHOD

      virtual const char* what() const throw() override
      {
               return "dude! whatch the index!!"
      }
};

int main()
{
     try
     {
           throw IndexOutOfBoundary(); // throw exception of your class
     }
     catch(exception& e) // use a base class
     {
           cout << e.what(); // virtualy calls your method with description 
     }
     cin.ignore();
     return 0;
}


PROGRAM OUTPUT:

dude! whatch the index!!
Last edited on
You already got a good answer on how to extend exception (remember to override the what()), but to answer the other questions

exception () throw(); // Is it legal? What does it mean by "exception ()"? If throw() is the function name, then "exception ()" should be replaced by an object type thrown. In this case, I think it's "exception".

"exception()" is a constructor that takes no arguments, that is the default constructor. The dynamic exception specification (not "function name") "throw()" informs the compiler that the function will not throw any exceptions. This syntax is deprecated: in the current standard, the constructor of std::exception is declared as exception() noexcept;.

exception (const exception&) throw(); // similar to the previous question. In addition, what's the extra "const exception &"?

The "extra" const exception& is this function's parameter. Objects of class std::exception are copyable, so the copy constructor is provided.

virtual const char* what() const throw(); // what is "what()"

what() is the explanatory string, which contains arbitrary text. It is how most standard C++ exceptions provide additional information about the error. If you're throwing a standard exception, you can set the string at the throw site, as in

1
2
3
4
    throw std::runtime_error("This is the explanatory string");
} catch(const std::exception& e) {
    std::cerr << "Caught " << e.what() << '\n';
}


When writing your own exception classes, you may also provide error codes (or derive from std::system_error, if your compiler has it) as a supplement to the explanatory string.
> The throw() is a throw specifier that is generally discouraged in production code.

AFAIK, the use of any dynamic exception specification is now deprecated. (Edit: Hadn't seen Cubbi's post which confirms this when I wrote this, hence the AFAIK)

So we now have just three non-deprecated forms:

1
2
3
4
5
6
void foo() ; // might throw anything

void bar() noexcept ; // will never throw

void baz( T a ) noexcept( sizeof(T) < 100 /* note: this must be a constexpr */ ) ;  
// will never throw if size of T is less than 101, might throw anything otherwise. 

In addition, C-library functions are deemed to be noexcept.


> class IndexOutOfBoundary : public exception { /*...*/ };

Prefer using virtual inheritance when deriving from an exception base class.
See: http://www.boost.org/community/error_handling.html

Last edited on
JLBorges,
thanks for that useful post!

but why this your example does not compile?
(I've replace T with int)
void baz( int a ) noexcept( sizeof(int) < 100 /* note: this must be a constexpr */ ) ;

however it works well so:
void baz( int a ) nothrow(sizeof(int) < 100) ;

cheers!
> ... this your example does not compile? ... however it works well so:

Hmm.. That is strange. AFAIK, it should be just the other way around. Which is the compiler?

noexcept: http://www2.research.att.com/~bs/C++0xFAQ.html#noexcept

std::nothrow: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=170
Thank you guys very much!
Everyone has been extremely helpful! Cheers.
JLBorges,
OH yeah, noexcept is C++0x future :D

I'm using MSVC++ and it obviously dons't support many new futures yet.

cheers!
Hi:

An extra question:

I see on stackoverflow that "throw(...)" implies the function might throw an exception of an unspecified type.
http://stackoverflow.com/questions/88573/should-i-use-an-exception-specifier-in-c



However, the specifier "throw(...)" doesn't compile on my compiler, gcc 4.4.3

The error code is:
"g++ -g -Wall -c test.cc
test.cc:5: error: expected type-specifier before ‘...’ token
test.cc:58: error: expected type-specifier before ‘...’ token
make: *** [test.o] Error 1
"


Is it(throw(...)) not a part of c++ standard?


In addition, if a function has no exception specifier at all, e.g.
void function1();, what is the difference between void function1(); and void function1() throw(...);? My guess is they are the same thing.

Thanks a lot.
> However, the specifier "throw(...)" doesn't compile on my compiler, gcc 4.4.3
> Is it(throw(...)) not a part of c++ standard?

Your compiler is right. Standard C++ does not have an exception specification throw(...)
the only place where throw(...) may be is behind funciton parameters like this:

void function(int a, double b) throw(...);

that means that this function may throw anything
however this is NOT a part of function signature.

what is the difference between void function1(); and void function1() throw(...);?
there is no difference, is second example you are explicitly telling that funciton may throw anything, and that is default behaviour.


link you posted from stackoverwlow:
1
2
3
void foo() throw(); // guaranteed not to throw an exception 
void bar() throw(int); // may throw an exception of type int 
void baz() throw(...); // may throw an exception of some unspecified type  


all that throw may appear only behind function signature as I said before.
howerver you may also pu a list of what function may throw like this:

void function(int a, double b) throw(int, char*, std::string, exception);

this tells that this function may throw only those specified things:
int,, char*, std::string and exception class.

if funciton throw anything else anyway then std::terminate will be called and your program terminates.

hope this help :D
Many thanks, guys!
Awesome answers!
Topic archived. No new replies allowed.