Exception Handling

  • Upload
    amable

  • View
    32

  • Download
    1

Embed Size (px)

DESCRIPTION

Exception handling (EH) allows a programmer to provide code in the program to handle run-time errors or exceptional situations this improves reliability EH was first introduced in PL/I and found in few languages (except for EOF-types of mechanisms) until C++ - PowerPoint PPT Presentation

Citation preview

  • Exception HandlingException handling (EH) allows a programmer to provide code in the program to handle run-time errors or exceptional situationsthis improves reliabilityEH was first introduced in PL/I and found in few languages (except for EOF-types of mechanisms) until C++EH has been included in most modern languages since C++ since their utility greatly improves reliabilityHere, we look at PL/I, Ada, C++ and Java and briefly consider Events as a special form of exceptiondesign issues:how/where are exception handlers specified and what is their scope?how is an exception bound to a handler?where does execution continue after the handler executes (continuation)how are user-defined exceptions specified, if at all?are there predefined exceptions? If so, should there be default handlers for them?can predefined exceptions be explicitly raised?are hardware errors treated as exceptions to be handled?should it be possible to disable predefined exceptions?

  • Binding and ContinuationException handler binding determines which handler can handle the exception

    Continuation determines what happens after the handler executes:return to the same statement that raised the exception (or the next one) end the block that contains the instruction that raised the exception terminate the program

  • PL/IUser-defined exception handlers can appear anywhere in the program (see below)condition is a pre-defined or user-defined exceptiontwo built-in conditions are ANYCONDITION and ERRORuser-defined exceptions work as follows:ON CONDITION (boolean)SNAP is a keyword to print out dynamic chain Reference environment is the code in which handler is embeddedBinding is dynamic: the handler is bound to the exception from the ON statement until either a new handler is definedthe end of the local block is reacheda revert statement is reachedBuilt-in exceptions all have built-in handlers but can be overridden by user-defined handlers you can enable or disable conditions (some default to being disabled)(NO condition) : statement; or(condition) : statement;Continuation can be a branch (using GO TO)continue with the same or next instr.termination of programGeneral form: ON condition [SNAP] BEGIN; END;

  • PL/I ExamplesAbove, SIZE is enabled, from the On instruction forward, a handler is defined for any SIZE error (the error handler simply does SNAP). The SIZE error handler continues to Operate in B, C, D and E because of dynamic binding (even though only C is inside of Bs static scoping)In the example below, handlers forEndfile are provided for two different filesBuilt-in exceptions include ENDPAGE, ENDFILE, CONVERSION, OVERFLOW, UNDERFLOW, ZERODIVIDE, SIZE, STRINGRANGE, SUBSCRIPTRNAGE, UNDEFINEDFILE

  • AdaAda exception handlers are defined using the following syntactic form:when exception_choice { | exception_choice} = > statementswhen is a reserved wordexception_choice is a pre-defined exception type or one defined by the programmer, and statements is a list of statementsother is an acceptable choice for exception_choice meaning that this is a default handler for all types of exceptions that do not have specific handlersHandlers are defined in a separate exception portion of a block of code as shown belowthey can also be listed outside of a subprogram but inside a package begin code here that can raise exceptions to be handled exception when exc_name1 => handler code here when exc_name2 => handler code here end;

  • Binding in AdaWhich handler is executed when an exception arises?if the block of code has an exception handler for the exception, then the exception is statically bound (that is, the handler in that block is used)otherwise, the exception is propagated as follows:if raised in a procedure, exception is propagated to the calling subprogram at the point of the callif that subprogram has no handler, the exception is propagated to its caller, etc until the exception reaches the main program in which case it is either handled there (if there is a handler) or the program terminatesif raised in a block, the exception is handled by the procedure that contains the block (an example of this follows), and if there is no handler, the exception propagates as described aboveif raised in a package body, then the handler of the package is used and if there is none, then it is propagated to whatever unit contains the package declarationif this is a library, then the program terminatesif the package defines the main program (e.g., not used by another) then the exception is ignored and execution continues!

  • Ada ContinuedThe block or procedure that raised the exception will be terminated automaticallycontinuation after exception handling either results in termination of the program if there is no handler, orcontrol returns to the body that invoked the unit that raised the exceptionif Main calls Sub1 and Sub1 raises the exception, after handling, control resumes with the instruction in Main after the call to Sub1if an exception is raised in a loop, the loop body is terminated, control resumes with the loop control (the loop may be re-entered if the loop condition is true)Other info:exceptions (conditions) can be explicitly disabledthere are 5 built-in exception categories:constraintprogramnumericstoragetaskingprogrammers can define further exceptionsexceptions can be raised explicitly through raise exception_name

  • Ada Example with Ada.Text_IO, Ada.Integer.Text_IO; use Ada.Text_IO, Ada.Integer.Text_IO; procedure Grade_Distribution is Freq : array(1..10) of Integer := (others => 0); New_Grade, Index, Limit_1, Limit_2 : Integer; begin loop Get(new_Grade); Index := New_Grade / 10 + 1; begin Freq(Index) := Freq(Index) + 1; exception when Constraint_Error => if New_Grade = 100 then Freq(10) := Freq(10) + 1; else Put_Line(Error new grade is out of range); end if; end; end loop; exception when End_Error => Put(Limits Frequency); for Index in 0..9 loop Limit_1 := 10 * Index; Limit_2 := Limit_1 + 9; if Index = 9 then Limit_2 := 100; end if; Put(Limit_1); Put(Limit_2); Put(Freq(Index+1)); New_Line; end loop; end Grade_Distribution;

  • C++Not implemented until after 1990handlers are placed in catch blocks following try blocksif an exception arises in the try block, control can be thrown to the associated catch blockif the code is not in a try block, any exception will not be handledtry and catch blocks are embedded within other code, such as a block or inside a functionexample: try { code with exception } catch (params) {} catch (params) {}exceptions can only be raised using an explicit throw statement as in throw (params);NOTE: a throw statement without parameters is possible but only in a handler, the result is that the handler re-invokes itselfthe type(s) of parameter(s) determine which catch is used for instance, throw(x); where x is an int will be caught by a catch(int p); but not by a catch(float p);

  • More on C++If an exception is raised in a try block, the block terminates and control goes to the proper catchcatch blocks are checked in order so for instance, if there are two catch blocks that catch an int, the first will be the only one to ever be useda catch that uses () for its parameters acts like an else (catches any throw)so it should only be listed at the end of all catch blocks for the given try blockif there is no catch to match the throw, then the exception is propagated to the next level or to the functions callerthe process terminates if an exception is propagated to main and there is no handler thereContinuation after a handler always returns to the first statement following the last handler in the sequencealthough a handler could re-invoke itselfThere are only user-defined exceptionsC++s exception handling is much simpler than Ada or PL/I

  • C++ Example #include void main() { int new_grade, index, limit1, limit2, freq[10] = {0,0,0,0,0,0,0,0,0,0}; short int eof_condition; try { while(1) {if(!cin >> new_grade) throw eof_condition;index = new_grade / 10; {try { if (index < 0 || index > 9) throw(new_grade); freq[index]++; } catch(int grade) {if(grade = = 100) freq[9]++; else cout
  • JavaIn Java, exceptions are objectsthere are already a number of built-in exception classes (all descended from the built-in class Throwable), as well as the facility to define your own exception classesThrowable has two built-in subclasses: Error - errors thrown by the Java interpreter such as out of heap memoryException - errors thrown by the user programexamples include NullPointerException, EOFException, FileNotFoundException, IOException, ArithmeticException, NegativeArraySizeException, and ArrayIndexOutOfBoundsExceptionas in C++, the programmer can raise an exception using the throw clausethrow new foo (Bad news);and like C++, there are Try and Catch clauses try { } catch (Exception foo) { }all Catchs must have a parameter which must be of a type that is a descendent of the class Throwable

  • Throwing, Catching, ContinuationBuilt-in exceptions will be thrown automatically if the exception arisesUser-defined exceptions are thrown explicitly through a throw statement (as in C++)built-in exceptions can also be thrown explicitlyThe catch block that catches an exception is based on the type of exception, not on a parameter typeexceptions can be handled in the given block or are propagated if the method explicitly states throws ExceptionType in its header, in which case the exception is propagated to the caller this can continue until the main program is reached in which case, if not handled, the program terminates

  • Finally, Continuation Aside from the throw and catch clauses, Java allows a finally clauseThe finally clause can be a clean up set of code for the object that is, if any exception arises, there might need to be some routine that makes sure the object can continueThe finally clause is always executed prior to continuation whether an exception arises or not and regardless of the type of exceptionContinuation occurs with the statement after the Try constructif there is none, then continuation occurs with the caller of the method and so forth up the run-time stackultimately, if no method is found, continuation occurs with the original application program or terminationA return statement in the handler terminates the method entirelyan example similar to the C++ example is given in the book on pages 639-641

  • ComparisonsIn PL/I, exception handling was complicated becausecontinuation could go anywhere (through GO TO statements)dynamic binding of handlers to code reduced readabilityIn Ada, there was an attempt to simplify exceptions but because of the difference between exceptions being raised in a block, procedure, package or loop, continuation was still complexIn both languages, defining your own exceptions was possibleIn C++, exception handling was simplified as much as possiblepossibly to the point of making it too weak since there are no user-defined exceptions, only programmer-specified throw statementsJava seems to have the best (so far) including the finally clause, and capabilities for user-defined as well as system-defined exceptionsC# also has exception handling that are similar to Java except that there is no throws clause for method headers

  • Event HandlingEvent handling can be thought of as a form of exception handlingtypically, exception handling is meant to convey that something unexpected arose, handle itand to prevent run-time error situations from causing program terminationbut recall the C++ and Ada programs from earlier, one exception was simply the exception that caused termination of the loopWe can treat other types of events in the same manneran event is simply the notification that something specific occurred, using with respect to input (mouse motion or button, key entry)an event handler is the code defined to handle the eventboth Java and JavaScript have event handling capabilities although the mechanisms differ from exception handling in Java, they are similarly related

    *In this figure, the executing code causes an exception to arise. Which handler should be invoked? This is binding. In some languages, this is based on the location of the handler with respect to the code, and thus is determined statically. In other languages, this is based on previously executed statements such as establishing a new handler for a given exception starting at this point forward.

    The other question is how to proceed after the handler executes. That is, what form of continuation should occur? PL/I gave a great many number of options including the use of go to statements. In most languages today, continuation is with the unit that called the code that raised the exception for instance, if function a calls function b and function b raises an exception that is handled, then continuation is with the next instruction in function a after the call to b.

    ****If not bound to the immediate block of code, then it follows one of several possibilities. The first possibility, bound to the block that called this procedure is similar to Java where you use throws Exception. In this case though, throwing the exception to the calling block is done automatically if needed. The second possibility is really the same as the default, handled locally. The third is the most complicated of the issues, if the exception arises in a package body, then it is either handled by exception handlers defined in the package, or handled by the unit that declared the package which means that it would be handled dynamically.

    **This example is used throughout this chapter. It uses exceptions primarily to allow the programming to code some conditions in a lazy fashion. Specifically, one condition arises when a student receives a grade of 100, and therefore the Freq of the 90-99 grade range is incremented. This could have been handled easily with an if statement that saysIf New_Grade = 100 then Freq(10) := Freq(10) + 1;else Freq(Index) := Freq(Index) + 1;The other exception is used to leave the infinite loop (loopend loop) rather than using a while loop based on an end of file or end of input situation.**It is ironic that C++, one of the most complex languages, has one of the simplest forms of exception handling. Since there are no built-in exceptions, exception handling is really a means to transfer control (like a go to statement) and so is of questionable use*******