Exceptions

C error handling.

There are several error handling techniques in C. Functions return error codes or save them in global error variables like errno. Signals can be sent and received on error. Can clash with other applications. Long jumps take the program out of the current context and into another. This has all the classic problems of gotos as well as not cleaning up if it can.

catch and throw

In C++, a function can detect an error and throw an object containing information about the error out into the world. Somewhere, some other function catches it and processes the error.

The syntax for a throw is:

throw classname(args);
This creates an instance of this class and effectively returns it from the function, even if that isn't the return type of the function. Usually the context of thrown errors is a try block. The code looks like:
try {
// some code that generates errors
}
catch(thrown_type1 var) {
// catcher code
}
catch(thrown_type2 var) {
// other catcher code
}

Only one catch clause is needed for each exception type, even if there are multiple throw statements in the try block. C++ supports the termination model. The assumption that the code throws an exception because things are so bad there is no help. If you want to construct the catchers so they try to fix the problem, put the try block inside a while loop.

To tell the user what the function is likely to throw as exceptions, there is an extention of the function definition syntax.

void foo() throw( toobig,badpointer);

function definition without a throw clause indicates that any exception can be thrown.

void foo() throw();

Means that no execptions will be thrown. Specifying the execeptions helps the user know what to do if they want to put a try loop around your code. generic catchers can be used.

catch(...) {
}

This should be put at the end of the catcher list to pick up any you missed. If you can't figure out what to do, putting a call to throw with no arguments in a catcher will cause the exception to be re-raised to be picked up in the next outer try block. To make sure everything is clean, when you leave the scope of the code that threw the exception, all objects that have been succesfully constructed, are destructed.

Use them for non-local errors. If you can handle it, do it. Use heirarchies of exceptions to help classify the error. Use reference parameters in catchers. Wrap a simple try block with a generic catcher around code and refine it as needed. Good to throw exceptions during construction so execution doesn't continue with incomplete code. Don't use exceptions in destructors. Scope changes call destructors and you might get in a loop.

Some built in exceptions

Standard exceptions
This is from here
Some functions of the standard C++ language library send exceptions that can be captured if we include them within a try block. These exceptions are sent with a class derived from std::exception as type. This class (std::exception) is defined in the C++ standard header file and serves as pattern for the standard hierarchy of exceptions:
exception    
  bad_alloc (thrown by new)  
  bad_cast (thrown by dynamic_cast when fails with a referenced type)  
  bad_exception (thrown when an exception doesn't match any catch)  
  bad_typeid (thrown by typeid)  
  logic_error  
    domain_error
    invalid_argument
    length_error
    out_of_range
  runtime_error  
    overflow_error
    range_error
    underflow_error
  ios_base::failure (thrown by ios::clear)  
Because this is a class hierarchy, if you include a catch block to capture any of the exceptions of this hierarchy using the argument by reference (i.e. adding an ampersand & after the type) you will also capture all the derived ones (rules of inheritance in C++).