FAQ 26.11 What should the unexpected() function do?

FAQ 26.11 What should the unexpected() function do?

graphics/new_icon.gif

Log the error and call terminate().

When a function has an exception specifier and the function throws an exception that doesn't match anything in its exception specifier list (Murphy's Law), the exception-handling mechanism calls unexpected(). By default, the unexpected() function silently calls the terminate() function, which is terminal. The behavior of unexpected() can and probably should be changed by using the set_unexpected() function:

 #include <cstdlib> #include <iostream> using namespace std; class Fred   { }; class Wilma  { }; void sample() throw(Fred) {   switch (rand() % 3) {     case 0:       cout << "throwing a Fred; ";       throw Fred();     case 1:       cout << "throwing a Wilma; ";       throw Wilma();                                 <-- 1     default:       cout << "returning normally; ";   } } 

(1) Danger

Note that the preceding user code expected to throw a Fred but never expected to throw a Wilma (see the exception specification immediately following the signature of sample()). In practice, this happens accidentally, such as when sample() calls a function that calls a function that calls a function that throws a Wilma. In any case, sample() is erroneous; either it must catch the Wilma or it must broaden its exception specification list to tell its users that it may throw a Wilma.

 #include <exception> void myUnexpected() throw() {   cout << "unexpected exception!" << endl;   terminate();  // Good night Nurse! } int main() {   // Without this, the program would silently crash:   set_unexpected(myUnexpected);   for (int i = 0; i < 10; ++i) {     try {       cout << "trying: ";       sample();       cout << "no exception thrown\n";     }     catch (Fred) {       cout << "caught a Fred\n";     }     catch (Wilma) {       cout << "caught a Wilma\n";     }     catch (...) {       cout << "this should never happen\n";     }   } } 

Saving the most recently thrown exception in a global variable can enhance the technique. That way the error message in myUnexpected() can be more intelligent, especially if all exceptions inherit from a common base class that provides some identification services. Obviously, access to such global variables must be serialized in multithreaded environments.

If a program is crashing silently before main() begins, it may be getting an unexpected exception during static initialization. In this case, it is necessary to set the unexpected function (set_unexpected(myUnexpected);) inside a constructor of a static object, but even then there are no guarantees since the static object may not get constructed (and therefore myUnexpected() function may not be registered) before the error occurs.



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net