Presentation is loading. Please wait.

Presentation is loading. Please wait.

Exception Handling Exception handling (EH) allows a programmer to provide code in the program to handle run-time errors or exceptional situations this.

Similar presentations


Presentation on theme: "Exception Handling Exception handling (EH) allows a programmer to provide code in the program to handle run-time errors or exceptional situations this."— Presentation transcript:

1 Exception Handling Exception handling (EH) allows a programmer to provide code in the program to handle run-time errors or exceptional situations this improves reliability The earliest form of EH was in FORTRAN where you could specify code to handle I/O errors READ(UNIT=5, FMT=1000, ERR=100, END=999) X, Y, Z UNIT is the device number, FMT, ERR and END denote line numbers that include the formatting information, what to do for an input error and what to do when EOF is reached most languages have some built-in mechanism for handling EOF (and maybe EOLN) but it wasn’t until PL/I that EH was introduced as a language feature EH has been included in most modern languages since C++ to improve language reliability here, we look at PL/I, Ada, C++ and Java

2 Design 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) is there a “finalize” capability to run whether an EH ran or not? How are user-defined exceptions specified, if at all? Can predefined exceptions be explicitly raised? can user defined exceptions be implicitly raised? no Are there predefined exceptions? should there be default handlers for them? Should it be possible to disable predefined exceptions? Are hardware errors treated as exceptions to be handled?

3 Binding and Continuation
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 the most recently defined EH to where the code that caused the EH is located. For instance, imagine that we have the following code where EH1, EH2 and EH3 are exception handlers to handle the exception that is raised. code part 1 EH1 code part 2 EH2 code part 3 EH3 code part 4 If the error arises in code part 1, no EH is available, program terminates. If code part 2 causes the exception, then EH1 is used. If code part 3 causes the exception then EH2 is used and if code part 4 causes the exception then EH3 is used. Notice if this is in a loop and on the next iteration code part 1 causes the exception then EH3 is used. The other question that this slide addresses 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. EH binding determines which handler is invoked to handle an exception Continuation determines what happens after the handler executes: return to the same statement (or the next one) end the block that contains the instruction that raised the exception terminate the program

4 PL/I User-defined exception handlers can appear anywhere in the program To specify that exception handling should take place, use an ON block see below where condition is either a pre-defined condition or a user-defined condition SNAP is a keyword to print out dynamic chain User-defined exceptions work as follows: ON CONDITION (boolean) if the condition is true, it establishes this tests the Boolean and establishes CONDITION if true CONDITION is an identifier ON condition [SNAP] BEGIN; END;

5 PL/I Exception Handling
Reference environment for any handler is the code in which handler is embedded Binding is dynamic: the handler is bound to the exception from the ON statement until either a new handler is defined the end of the local block is reached a REVERT statement is reached After the execution of a handler, continuation can be a branch (using GO TO or CALL) continue with the same or next instr termination of program

6 PL/I Exceptions Built-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) (NOcondition) : statement; or (condition) : statement; Built-in exceptions include Memory/File handling: ENDPAGE, ENDFILE, UNDEFINEDFILE Arithmetic: CONVERSION, OVERFLOW, UNDERFLOW, ZERODIVIDE, SIZE (loss of precision) String/Array: STRINGSIZE, STRINGRANGE, SUBSCRIPTRANGE

7 PL/I Examples The example below defines two
handlers for endfile exceptions Condition SIZE is enabled From the On instruction forward, a handler is defined for any SIZE error (the error handler simply does “SNAP”) where the SIZE error handler continues to operate in B, C, D and E because of dynamic binding

8 Ada Ada exception handlers are defined using the following syntactic form: when exception_choice { | exception_choice} = > statements when is a reserved word exception_choice is a pre-defined exception type or one defined by the programmer, and statements is the handler other is an acceptable choice for exception_choice meaning that this is a default handler for all types of exceptions that do not have specific handlers example shown on the next slide

9 Continued Handlers are defined in a separate exception portion of a block of code as shown below they can also be listed outside of a subprogram but inside a package exception is a reserved word to indicate the exception handling portion of this block of code begin … code that can raise exceptions exception when exc_name1 => handler code here when exc_name2 => handler code here end;

10 Binding in Ada Which handler is executed when an exception arises?
This depends on context if the block of code has an exception handler for the exception, then the exception is statically bound otherwise, the exception is propagated as follows: if raised in a procedure, exception is propagated to the calling subprogram (and upward through the stack of calls until a procedure is reached which has a handler defined for the exception) if no handler is found, program terminates if 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 declaration if this is a library, then the program terminates if the package defines the main program (e.g., not used by another) then the exception is ignored and execution continues! Note that the first two forms of propagation are pretty much the same as in Java. Handled through a local catch block or thrown to the method that called this method to that catch block and if there is no catch there, then thrown…

11 Continuation in Ada The block or procedure that raised the exception will be terminated automatically Control returns to the body that invoked the unit that raised the exception if Main calls Sub1 and Sub1 raises the exception, after handling the exception, control resumes with the instruction in Main after the call to Sub1 if 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)

12 Other Information on Ada EH
Exceptions (conditions) can be explicitly disabled There are 5 built-in exception categories: constraint (e.g., array subscript errors, range error) program numeric (arithmetic) storage tasking Programmers can define further exceptions Exceptions can be raised explicitly through raise exception_name

13 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 Grade_Loop: loop begin Get(new_Grade); exception when Data_Error => exit Grade_Loop; end; Index := New_Grade / ; Freq(Index) := Freq(Index) + 1; when Constraint_Error => Ada Example This example uses exceptions so that the programmer can be lazy about indicating conditions. The first exception handler (inside the loop) is invoked if Freq(Index) causes an error, which is the case if New_Grade > 99. We could have handled this with a simple if statement instead as shown here: If New_Grade > 100 Put_Line(“Error – new grade is out of range”) else if 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 (loop…end loop) rather than using a while loop based on an end of file or end of input situation.

14 if New_Grade = 100 then Freq(10) := Freq(10) + 1; else Put_Line(“Error – new grade”); 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; Put(Limit_1); Put(Limit_2); Put(Freq(Index+1)); New_Line; end Grade_Distribution;

15 C++ Not implemented until after 1990
if code might generate an exception, place it in a try block follow the try block with one or more catch blocks to catch the exception if the code is not in a try block, any exception raised will not be handled you must have at least one catch block after any try block (otherwise it’s a syntax error) try and catch blocks are embedded within other code (inside a function or method) example: try { … code with exception … } catch (params) {…} catch (params) {…} exceptions can only be raised using an explicit throw statement as in throw(param(s)); NOTE: a throw statement without parameters is possible but only in a handler, the result is that the handler re-invokes itself

16 Binding Handlers are placed in catch blocks that follow the try block that can raise an exception via a throw a throw does not have to be from within a try block but can be from within a function/method called from the try block in which case binding occurs with the catch blocks after the try block in the calling unit, not the called unit – that is, the throw is propagated up the run-time stack if there are no try/catch blocks to catch the exception, a runtime error is generated the handler selected is based on the type of parameter thrown assume x is an int and y is a float catch(int p) {…} catches throw(x); catch(float p) {…} catches throw(y); 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

17 Binding (cont) and Continuation
Catch blocks are checked in order so if two catch blocks have the same profile, the earliest one is used a catch block can use (…) for its parameters to serve as a default (that is, to catch anything not caught above it) Continuation occurs with the first instruction after the try and catch blocks if the try/catch blocks end the function/method, then continuation is with whatever unit called the function/method however, a handler could re-invoke itself There are only user-defined exceptions and exceptions can only be explicitly raised this makes C++’s exception handling much simpler than Ada or PL/I but also much weaker

18 C++ Example 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 << “Error – new grade”; } // catch } // inner try } // while } // outer try catch(short int) { … } } // main C++ Example

19 Java In Java, exceptions are objects
there are already a number of built-in exception classes (all descended from the built-in class Throwable), as well as a facility to define your own exception classes Throwable has subclasses of Error (thrown by the JVM) and Exception (thrown by the user program) as in C++, the programmer can raise an exception using the throw clause throw new Foo (“Bad news”); and like C++, there are try and catch clauses try { … } catch (Exception foo) { … } all catch statements must have a parameter which must be of a type that is a descendent of the class Throwable

20 Throwing, Catching, Continuation
Built-in exceptions will be thrown automatically if the exception arises User-defined exceptions are thrown explicitly through a throw statement (similar to C++) built-in exceptions can also be thrown explicitly The catch block that catches an exception is based on the type of exception (rather than a primitive type like C++) exceptions can be handled in the given block or are propagated if the method explicitly states throws ExceptionType in its header propagation can continue until the main program is reached in which case, if not handled, the program terminates

21 Finally, Continuation Aside from the throw and catch clauses, Java allows a finally clause to “clean up” code The finally clause is always executed prior to continuation whether an exception arises or not and regardless of the type of exception Continuation occurs with the statement after the try block if there is none, continuation occurs with the caller of the method and so forth up the run-time stack ultimately, if no method is found, continuation occurs with the original application program or termination A return statement in the handler terminates the method entirely if you need to see an example, see the textbook. The try-throw-catch-finally strategy is common in newer languages.

22 Comparisons In PL/I, exception handling was complicated because
continuation could be to anywhere in the program (through GO TO statements) dynamic binding of handlers to code reduced readability In 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 complex In both languages, defining your own exceptions was possible

23 Continued In C++, exception handling was simplified as much as possible possibly to the point of making it too weak since there are no user-defined exceptions, only programmer-specified throw statements in essence, the exception would have to be detected by your code, in which case you could have just handled the situation with an if-else statement rather than a try-throw-catch Java provided the cleanest form built-in and user-defined exceptions easy ability to propagate exceptions when needed the finally clause Newer languages have adopted approaches like that of Java – for instance C# is similar to Java except for no explicit throws statement in a method header Not covered in these notes is the Python and Ruby forms of EH that are in the textbook. Python uses something similar to Java although the syntax looks somewhat like Ada: try: // try block here except Exception1: // EH for Exception1 here except Exception2: // EH for Exception2 here else: // this block of code executes if no exception is raised finally: // this block of code executes last no matter if an exception is raised or not NOTE: we are skipping the three sections on event handling covered in this chapter.


Download ppt "Exception Handling Exception handling (EH) allows a programmer to provide code in the program to handle run-time errors or exceptional situations this."

Similar presentations


Ads by Google