Another Look Upon Exceptions

来源:互联网 发布:商业办公软件 编辑:程序博客网 时间:2024/05/24 02:01
    As David Abrahams said in his article Exception-Safety in Generic Components: Nobody ever spoke of "error-safety" before C++ had exceptions. I think it's mainly because everyone uses his own ways to handle errors(or exceptions), and they see exceptions as a normal, well-expected case in program logics. Yet today, after 10 years of the standardization of C++, the amount of exception-handling code is larger -- in some case -- than the normal logic code. What makes such a difference? The exceptions? Or rather, our ways of treating exceptions?
   
    One thing for sure, exceptions provide many benefits:
    (1) A standardized way of handling errors
    (2) Error-handling code is departed out of the normal logics so that readability is enhanced.
    (3) Exceptions are added into C++ Core Language mechanisms so that compilers can do some optimizations to make programs more efficient.

    Yet, along with the benefits, exceptions bring out many problems. An article by Tom Cargill said that exceptions may lull programmers into a false sense of security, since the really hard part of coding exceptions are not the throws and catches, but are to prevent the resources, such as heap memories, from leaking and keep the programs in a well-defined state so that the programs are not to break down. These alone, of course, may well be difficult.
     My concerns over the exceptions are that how should we use exceptions as a way to reduce the errors occurred in the programs, and simultaneously, the costs of both performance and expenses? What level should we keep?
    There's no denying that some designers and a certain number of programmers still prefer old ways to exceptions while handling errors, for they need errors to be solved right where they occurred. In many cases, it'd be impossible to know how to deal with the errors and recover from it (they never know what the client want).

    On the other hand, coding exceptions needs "extraordinary care" as to keep the exceptions in a limited range without damaging the rest of the program. This "extraordinary care", however, may lead to a sharp, sky-rocketing increment of both designing and maintaining costs as well as the growth of the amount of the code, and, if unlucky, the new errors introduced.

     Honestly, there has not yet been an effective way to balance between the benefits and costs of exception-handling. Yet here are some strategies that are worth considering:

     (1) Let no exceptions slip through the destructors
     Consider this:
     {
         someClass a; //a class whose destructor may throw an exception
         a.someMethod(); //exception occurs here
     }
     While stack-unwinding, class a's destructor will be called. What happens when the destructor throws an exception? Undefined! What is worse, this kind of errors are not easily driven. In most aspects, it is a terrible design when a destructor must throw an exception(of any kind).
     (2) Keep exceptions in a certain range, such as modules or namespaces.
     Some exceptions are public, such as std::bad_alloc in operator new. Their purpose is to let the users decide whether to solve the problems(in most cases, it is “yes”) and how to solve them. Whereas others, the private exceptions, they should be kept in a limited range so that they are not spreading everywhere, causing exception pollutions(sounds like a monster in a cage, isn't it). This method may benefit when trouble-shooting and debugging.
     (3) Establish a standard for coding exceptions
     As many other coding standards do, standards for exceptions may help standardize and unify the style and format specialized for coding with exceptions in a project team. Every one knows how important a standard means.
     (4) Use RAII and transaction mechanisms if possible
     RAII(Resource Acquisition Is Initialization) is a mechanism widely used among C++ programs, such as std::auto_ptr, boost::shared_ptr, etc. It is elegant as well as effective in preventing resource leaks. A transaction mechanism provides a way that acts like an “undo” button in a text editor. The program may roll back to the last well-defined state so as to keep the program going. As is stated above, the really hard part of coding exceptions is to keep the program in a well-defined state.

     There may well be other ways for coding with exceptions; and I realize that new problems will arise with the development of C++. If you have any idea of either exceptions or C++ problems or solutions, you can contact me at XuHotdogs@gmail.com

     A little more knowledge might light our way.

     References
     Exception Handling: A False Sense of Security by Tom Cargill, C++ Report, Nov-Dec 1994
     Exception-Safety in Generic Components: Lesson Learned from Specifying Exception-Safety for the C++ Standard Library by David Abrahams